1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 大华 sdk java_[日常总结] 大华SDK基于Java的二次开发实现Restful Api

大华 sdk java_[日常总结] 大华SDK基于Java的二次开发实现Restful Api

时间:2021-11-14 08:37:57

相关推荐

大华 sdk java_[日常总结] 大华SDK基于Java的二次开发实现Restful Api

最近半个月在对接大华摄像头,要实现摄像头的实时预览、云台控制和截图等功能。在网上找了很多资源也没有找到想要的,所以自己写了工具类。简单陈述一下基于大华的官网SDK实现摄像头的云台控制和抓图。无非就是调用SDK提供的一些函数来实现。

1. 首先先看看大华给的开发流程

image.png

开发可以顺着这个流程图的步骤,就会变得简单明了,开发其他功能也一样,下面是我封装好的工具类。至于一些引用类都是在大华官网的SDK里面。

云台控制

/**

* @author : colors

* @date : 11:04 /12/3

* 云台控制工具类

*/

public class PTZControlUtil {

// 初始化sdk

public static NetSDKLib netsdk = SDK_INSTANCE;

// 设备信息

private static _DEVICEINFO_Ex m_stDeviceInfo = new _DEVICEINFO_Ex();

// 登陆句柄

private static NetSDKLib.LLong m_hLoginHandle = new NetSDKLib.LLong(0);

// 网络断线处理

private static DisConnect disConnect = new DisConnect();

// 设备连接恢复,实现设备连接恢复接口

private static HaveReConnect haveReConnect = new HaveReConnect();

/**

* 云台控制

* 向上移动

*

* @param m_strIp ip

* @param m_nPort 端口

* @param m_strUser 登录名

* @param m_strPassword 密码

* @param nChannelID 通道id 默认为0

* @param lParam1 默认 0,当有左上或左下等操作时才会传值 (1-8)

* @param lParam2 垂直/水平 移动速度 (1-8)

*/

public static void upControlPtz(String m_strIp, int m_nPort, String m_strUser, String m_strPassword, int nChannelID, int lParam1, int lParam2) {

// 初始化

LoginModule.init(disConnect, haveReConnect);

// 若未登录,先登录。

if (m_hLoginHandle.longValue() == 0) {

login(m_strIp, m_nPort, m_strUser, m_strPassword);

}

// 开始向上移动,若超过角度则会变为左右移动

if (m_hLoginHandle.longValue() != 0) {

System.out.println("开始向上移动..., 当前速度为:" + lParam2);

startUpControl(nChannelID, lParam1, lParam2);

}

System.out.println("操作完成");

// 停止移动

stopUpControl(nChannelID);

// 退出

logout();

System.out.println("退出登录...");

// 释放资源

LoginModule.cleanup();

}

// 向上

private static void startUpControl(int nChannelID, int lParam1, int lParam2) {

if (m_hLoginHandle.longValue() != 0) {

netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, nChannelID,

_PTZ_UP_CONTROL,

lParam1, lParam2, 0, 0);

} else {

System.err.println("登录句柄不存在!");

}

}

private static void stopUpControl(int nChannelID) {

netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, nChannelID,

_PTZ_UP_CONTROL,

0, 0, 0, 1);

}

// 上下左右等其他一些操作只是指令不同 ,此处就省略了

/**

* 登录

*

* @param m_strIp ip

* @param m_nPort 端口号

* @param m_strUser 账号

* @param m_strPassword 密码

* @return 成功则 true

*/

public static boolean login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {

//IntByReference nError = new IntByReference(0);

//入参

_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new _IN_LOGIN_WITH_HIGHLEVEL_SECURITY();

pstInParam.nPort = m_nPort;

pstInParam.szIP = m_strIp.getBytes();

pstInParam.szPassword = m_strPassword.getBytes();

pstInParam.szUserName = m_strUser.getBytes();

//出参

_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new _OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();

pstOutParam.stuDeviceInfo = m_stDeviceInfo;

m_hLoginHandle = netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);

System.out.println(netsdk.getClass());

if (m_hLoginHandle.longValue() == 0) {

System.err.printf("登录失败!\n", m_strIp, m_nPort, ToolKits.getErrorCodePrint());

} else {

System.out.println("登录成功: [ " + m_strIp + " ]");

}

return m_hLoginHandle.longValue() == 0 ? false : true;

}

/**

* 退出登录

*/

private static boolean logout() {

if (m_hLoginHandle.longValue() == 0) {

return false;

}

boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle);

if (bRet) {

m_hLoginHandle.setValue(0);

}

return bRet;

}

// 设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数

private static class DisConnect implements NetSDKLib.fDisConnect {

public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {

System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);

}

}

// 网络连接恢复,设备重连成功回调

// 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数

private static class HaveReConnect implements NetSDKLib.fHaveReConnect {

public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {

System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);

}

}

2. 抓图功能

先看看官网给的流程图,步骤3 看自己需求来调用函数

image.png

下面是封装好的工具类,可直接食用。

public class CapturePictureUtil {

private static NetSDKLib netsdk = SDK_INSTANCE;

private static _DEVICEINFO_Ex m_stDeviceInfo = new _DEVICEINFO_Ex();

private static NetSDKLib.LLong m_hLoginHandle = new NetSDKLib.LLong(0);

private static DisConnect disConnect = new DisConnect();

private static HaveReConnect haveReConnect = new HaveReConnect();

private static fCaptureReceiveCB m_CaptureReceiveCB = new fCaptureReceiveCB();

/**

* 封装抓图方法

*

* @param m_strIp 设备ip

* @param m_nPort 设备端口

* @param m_strUser 账号

* @param m_strPassword 密码

* @param chn 通道id

* @param mode 请求一帧 默认 0

* @param interval 时间单位秒:默认 0

*/

public static void capturePicture(String m_strIp, int m_nPort, String m_strUser, String m_strPassword, int chn, int mode, int interval) {

// 初始化sdk

LoginModule.init(disConnect, haveReConnect);

// 登录

if (m_hLoginHandle.longValue() == 0) {

login(m_strIp, m_nPort, m_strUser, m_strPassword);

}

// 截图

if (m_hLoginHandle.longValue() != 0) {

snapPicture(chn, mode, interval);

}

try {

synchronized (fCaptureReceiveCB.class) {

// 默认等待 3s, 防止设备断线时抓拍回调没有被触发,而导致死等

fCaptureReceiveCB.class.wait(3000L);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("--> " + Thread.currentThread().getName() + " CLIENT_SnapPictureEx Success." + System.currentTimeMillis());

logout();

LoginModule.cleanup();

}

/*

* 登录

*/

public static boolean login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {

//入参

_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new _IN_LOGIN_WITH_HIGHLEVEL_SECURITY();

pstInParam.nPort = m_nPort;

pstInParam.szIP = m_strIp.getBytes();

pstInParam.szPassword = m_strPassword.getBytes();

pstInParam.szUserName = m_strUser.getBytes();

//出参

_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new _OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();

pstOutParam.stuDeviceInfo = m_stDeviceInfo;

m_hLoginHandle = netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);

System.out.println(netsdk.getClass());

if (m_hLoginHandle.longValue() == 0) {

System.err.printf("登录失败!\n", m_strIp, m_nPort, ToolKits.getErrorCodePrint());

} else {

System.out.println("登录成功: [ " + m_strIp + " ]");

}

return m_hLoginHandle.longValue() == 0 ? false : true;

}

/**

* 退出登录

*/

private static boolean logout() {

if (m_hLoginHandle.longValue() == 0) {

return false;

}

boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle);

if (bRet) {

m_hLoginHandle.setValue(0);

}

return bRet;

}

/**

* 抓图方法

*

* @param chn 通道号

* @param mode 默认 0

* @param interval 默认0

* @return 成功返回ture

*/

private static boolean snapPicture(int chn, int mode, int interval) {

setSnapRevCallBack(m_CaptureReceiveCB);

// send caputre picture command to device

NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS();

stuSnapParams.Channel = chn; // channel

stuSnapParams.mode = mode; // capture picture mode

stuSnapParams.Quality = 3; // picture quality

stuSnapParams.InterSnap = interval; // timer capture picture time interval

stuSnapParams.CmdSerial = 0; // request serial

IntByReference reserved = new IntByReference(0);

if (!netsdk.CLIENT_SnapPictureEx(m_hLoginHandle, stuSnapParams, reserved)) {

System.err.printf("CLIENT_SnapPictureEx Failed!" + ToolKits.getErrorCodePrint());

return false;

} else {

System.out.println("CLIENT_SnapPictureEx success");

}

return true;

}

/**

* 保存图片

*/

private static class fCaptureReceiveCB implements NetSDKLib.fSnapRev {

BufferedImage bufferedImage = null;

public void invoke(NetSDKLib.LLong lLoginID, Pointer pBuf, int RevLen, int EncodeType, int CmdSerial, Pointer dwUser) {

if (pBuf != null && RevLen > 0) {

String strFileName = SavePath.getSavePath().getSaveCapturePath();

System.out.println("strFileName = " + strFileName);

byte[] buf = pBuf.getByteArray(0, RevLen);

ByteArrayInputStream byteArrInput = new ByteArrayInputStream(buf);

try {

bufferedImage = ImageIO.read(byteArrInput);

if (bufferedImage == null) {

return;

}

ImageIO.write(bufferedImage, "jpg", new File(strFileName));

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

/**

* 抓图回调函数

*

* @param cbSnapReceive

*/

private static void setSnapRevCallBack(NetSDKLib.fSnapRev cbSnapReceive) {

netsdk.CLIENT_SetSnapRevCallBack(cbSnapReceive, null);

}

// 设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数

private static class DisConnect implements NetSDKLib.fDisConnect {

public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {

System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);

}

}

// 网络连接恢复,设备重连成功回调

// 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数

private static class HaveReConnect implements NetSDKLib.fHaveReConnect {

public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {

System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);

}

}

结果:

image.png

更新

记录一下踩到的坑:大华SDK部署在windows 环境和 Linux环境不一样,在Linux环境中需要从环境变量里面去加载库文件且 NetSDKLib 接口中的 fDisConnect 继承的类不一样,需要更换,不然会报异常:lang.IllegalArgumentException:Invalid calling convention 63。

欢迎留言交流。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。