大华摄像头windows、linuxJavaSDK开发使用

文章目录

  • 简介
  • 环境要求
  • 库加载问题及解决方法
  • 大华摄像头Java SDK,完成摄像头设备登录、视频录像
  • 目录结构
    • windows 的c++代码
    • Linux的C++代码
    • 项目结构
  • 登录
  • 云台控制
  • 录像
  • 调用的接口
  • 注意
  • 码云地址

简介

本文档主要介绍 SDK 接口参考信息,包括主要功能、接口函数和回调函数。
主要功能包括:SDK 初始化、设备登录、实时预览、云台控制、语音对讲、报警监听、智能订阅、
录像回放和录像下载等。
根据环境不同,开发包包含的文件会不同,具体如下所示。
Windows 开发包所包含的文件如下:
在这里插入图片描述
Linux 开发包所包含的文件如下:
在这里插入图片描述
SDK 的功能库和配置库是必备库。
功能库是设备网络 SDK 的主体,主要用于网络客户端与各类产品之间的通讯交互,负责远程
控制、查询、配置及码流数据的获取和处理等。
配置库针对配置功能的结构体进行打包和解析。
推荐使用播放库进行码流解析和播放。

环境要求

1、推荐内存:不低于 512 MB。
2、Jdk 使用版本:jdk1.6;jdk1.8
3、SDK 支持的系统:

  • Windows 10/Windows 8.1/Windows 7/vista/XP/2000 以及 Windows Server 2008/2003。
  • Linux Red Hat/SUSE 等通用 Linux 系统

库加载问题及解决方法

目前提供 Windows(.dll)、Linux(.so)两种平台的动态库。其中 win 和 linux 分为 64 位、32 位版本。
而调用 C++动态库的主要的方式分为“直接使用 Java 项目”和“将 Java 项目作为其他项目的 jar
包依赖运行”两种。在加载库的过程中会出现“找不到动态库”的相关错误。
“找不到动态库”问题的根本原因为代码路径和物理路径不匹配。因为 linux 版本的动态库名称
相较于 Windows 版本多出 lib 前缀,故 Linux 环境下加载动态库需要注意 lib 的前缀,在拼接动态
库路径时需要加上 lib 前缀。使用 java.io.tmpdir 方式实现路径映射时,需要注意此种方式优先级
较低。

大华摄像头Java SDK,完成摄像头设备登录、视频录像

下载大华摄像头Java sdk

下载好项目部署所在服务器类型的sdk,如果windows 与linux 都要部署或使用可以将两个版本的sdk都下载下来,然后共用一套java代码,只需要判断当前系统类型然后加载不同的libs就好了。

目录结构

在这里插入图片描述

doc是sdk的文档存放路径
libs是c++依赖库
res是国际化相关配置

在这里插入图片描述

windows 的c++代码

在这里插入图片描述

Linux的C++代码

在这里插入图片描述

项目结构

Common包与lib包为大华sdk封装的代码,直接copy过来就好
在这里插入图片描述

libs包下有一个jnajar包,这个jar包可以通过maven命令打入本地厂库或者直接引入

按照demo的封装,进行自己的封装,以下是api包下的代码

登录

代码是否可用可直接运行main方法

import com.netsdk.common.Res;
import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Vector;

/**
 * 设备登录
 */
@Slf4j
@Data
public class DeviceLoginControl {
    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    public NetSDKLib configsdk = NetSDKLib.CONFIG_INSTANCE;
    public NetSDKLib.LLong m_hPlayHandleOne = new NetSDKLib.LLong(0);
    private Vector<String> chnlist = new Vector<String>();
    public NetSDKLib.LLong m_hPlayHandleTwo = new NetSDKLib.LLong(0);
    // 设备信息
    public NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
    private NetSDKLib.LLong lRealHandle;
    private String videoStoragePath;

    private Long cycleTime;
    private Long cleanCycle;
    // 登陆句柄
    public NetSDKLib.LLong m_hLoginHandle = new NetSDKLib.LLong(0);

    private static boolean bInit = false;
    private static boolean bLogopen = false;

    public DeviceLoginControl() {
    }

    public DeviceLoginControl(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect fHaveReConnect) {
        init(disConnect, fHaveReConnect);
    }

    public boolean init(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {
        bInit = netsdk.CLIENT_Init(disConnect, null);
        if (!bInit) {
            log.info("Initialize SDK failed");
            return false;
        }
        //打开日志,可选
        NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        File path = new File("./sdklog/");
        if (!path.exists()) {
            path.mkdir();
        }
        String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + ToolKits.getDate() + ".log";
        setLog.nPrintStrategy = 0;
        setLog.bSetFilePath = 1;
        System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        System.out.println(logPath);
        setLog.bSetPrintStrategy = 1;
        bLogopen = netsdk.CLIENT_LogOpen(setLog);
        if (!bLogopen) {
            log.error("Failed to open NetSDK log");
        }

        // 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作
        // 此操作为可选操作,但建议用户进行设置
        netsdk.CLIENT_SetAutoReconnect(haveReConnect, null);

        //设置登录超时时间和尝试次数,可选
        int waitTime = 5000; //登录请求响应超时时间设置为5S
        int tryTimes = 1;    //登录时尝试建立链接1次
        netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);


        // 设置更多网络参数,NET_PARAM的nWaittime,nConnectTryNum成员与CLIENT_SetConnectTime
        // 接口设置的登录设备超时时间和尝试次数意义相同,可选
        NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
        netParam.nConnectTime = 10000;      // 登录时尝试建立链接的超时时间
        netParam.nGetConnInfoTime = 3000;   // 设置子连接的超时时间
        netParam.nGetDevInfoTime = 3000;//获取设备信息超时时间,为0默认1000ms
        netsdk.CLIENT_SetNetworkParam(netParam);

        return true;
    }
 	public static void main(String[] args) throws IOException {
        DeviceLoginControl deviceLoginControl = new DeviceLoginControl();
        deviceLoginControl.login("ip", 37777, "username", "password");
    }


    public boolean login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
        //IntByReference nError = new IntByReference(0);
        //入参
        NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstInParam.nPort = m_nPort;
        pstInParam.szIP = m_strIp.getBytes();
        pstInParam.szPassword = m_strPassword.getBytes();
        pstInParam.szUserName = m_strUser.getBytes();
        //出参
        NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstOutParam.stuDeviceInfo = m_stDeviceInfo;
        //m_hLoginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, 0, null, m_stDeviceInfo, nError);
        m_hLoginHandle = netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
        if (m_hLoginHandle.longValue() == 0) {
            System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort, ToolKits.getErrorCodePrint());
        } else {
            System.out.println("Login Success [ " + m_strIp + " ]");
        }

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

   
    public void realPlayByDataType() {

        // 创建Stin对象 设置码流格式 通道号  预览类型 用户数据 保存文件名称
        NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE stIn = new NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE();

        stIn.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_GBPS;
        stIn.nChannelID = 0;
        stIn.rType = NetSDKLib.NET_RealPlayType.NET_RType_Realplay;

        stIn.dwUser = null;
        stIn.szSaveFileName = "D:\\DahuaResult\\result.flv";   // 转换后的裸H264码流文件名

        // 创建Stout对象
        NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE stOut = new NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE();

        // 预览转码流保存
        NetSDKLib.LLong lRealHandle = netsdk.CLIENT_RealPlayByDataType(m_hLoginHandle, stIn, stOut, 5000);
        if (lRealHandle.longValue() != 0) {
            System.out.println("RealPlayByDataType Succeed!");
        } else {
            System.err.printf("RealPlayByDataType Failed!Last Error[0x%x]\n", netsdk.CLIENT_GetLastError());
            return;
        }
        try {
            // 录像时间 单位毫秒
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 停止预览
        netsdk.CLIENT_StopRealPlay(lRealHandle);   // 必须停止拉流后,才会生成文件


    }
    public boolean logout() {
        netsdk.CLIENT_StopRealPlayEx(this.m_hPlayHandleOne);
        netsdk.CLIENT_StopRealPlayEx(this.m_hPlayHandleTwo);
        if (m_hLoginHandle.longValue() == 0) {
            return false;
        }
        boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle);
        if (bRet) {
            m_hLoginHandle.setValue(0);
        }
        for (int i = 0; i < m_stDeviceInfo.byChanNum; i++) {
            chnlist.clear();
        }
        return true;
    }
}

云台控制

import com.netsdk.lib.NetSDKLib;

public class PtzControl {
    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;

    public static boolean ptzControlStart(NetSDKLib.LLong m_hLoginHandle, Integer NET_PTZ_ControlType) {
        return netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, 0, NET_PTZ_ControlType, 2, 4, 0, 0);
    }

    public static boolean ptzControlEnd(NetSDKLib.LLong m_hLoginHandle, Integer NET_PTZ_ControlType) {
        return netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, 0, NET_PTZ_ControlType, 0, 0, 0, 1);
    }

    /**
     * 向上
     */
    public static boolean ptzControlUpEnd(NetSDKLib.LLong m_hLoginHandle) {
        return netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, 0, NetSDKLib.NET_PTZ_ControlType.NET_PTZ_UP_CONTROL, 0, 0, 0, 1);
    }

    /**
     * 向下
     */

    public static boolean ptzControlDownEnd(NetSDKLib.LLong m_hLoginHandle) {
        return netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, 0, NetSDKLib.NET_PTZ_ControlType.NET_PTZ_DOWN_CONTROL, 0, 0, 0, 1);
    }

    /**
     * 向左
     */

    public static boolean ptzControlLeftEnd(NetSDKLib.LLong m_hLoginHandle) {
        return netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, 0, NetSDKLib.NET_PTZ_ControlType.NET_PTZ_LEFT_CONTROL, 0, 0, 0, 1);
    }

    /**
     * 向右
     */

    public static boolean ptzControlRightEnd(NetSDKLib.LLong m_hLoginHandle) {
        return netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, 0, NetSDKLib.NET_PTZ_ControlType.NET_PTZ_RIGHT_CONTROL, 0, 0, 0, 1);
    }

    public static boolean ptzControl(NetSDKLib.LLong m_hLoginHandle, Integer NET_PTZ_ControlType) {
        boolean b = netsdk.CLIENT_DHPTZControlEx(m_hLoginHandle, 0, NET_PTZ_ControlType, 0, 0, 0, 1);
        return b;
    }
}

录像

import com.netsdk.lib.NetSDKLib;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class VideoControl {
    public static void startRealPlay() throws FileNotFoundException {
        DeviceLoginControl deviceLoginControl = new DeviceLoginControl();
        deviceLoginControl.login("192.168.0.108", 37777, "admin", "admin123");
        NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE stIn = new NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE();
        stIn.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_GBPS;
        stIn.nChannelID = 0;
        stIn.rType = NetSDKLib.NET_RealPlayType.NET_RType_Realplay;
        File xfile = new File("a.dav");
        FileOutputStream fos = new FileOutputStream(xfile);
        stIn.cbRealData = new NetSDKLib.fRealDataCallBackEx() {
            @Override
            public void invoke(NetSDKLib.LLong lRealHandle, int dwDataType, Pointer pBuffer, int dwBufSize, int param, Pointer dwUser) {
                // 指定回调流为PS格式
                if (dwDataType == 1001) {
                    byte[] byteArray = pBuffer.getByteArray(0, dwBufSize);
                    try {
                        fos.write(byteArray);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        stIn.dwUser = null;
        stIn.szSaveFileName = "D:\\result.flv";   // 转换后的裸H264码流文件名
        // 创建Stout对象
        NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE stOut = new NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE();
        // 预览转码流保存
        NetSDKLib.LLong lRealHandle = deviceLoginControl.netsdk.CLIENT_RealPlayByDataType(deviceLoginControl.m_hLoginHandle, stIn, stOut, 5000);
        if (lRealHandle.longValue() != 0) {
            System.out.println("RealPlayByDataType Succeed!");
        } else {
            System.err.printf("RealPlayByDataType Failed!Last Error[0x%x]\n", deviceLoginControl.netsdk.CLIENT_GetLastError());
        }
    }

    public static void videoRecording(DeviceLoginControl deviceLoginControl) {
        NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE stIn = new NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE();
        stIn.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_GBPS;
        stIn.nChannelID = 0;
        stIn.rType = NetSDKLib.NET_RealPlayType.NET_RType_Realplay;
        stIn.dwUser = null;
        log.info("设备登录信息:{}", deviceLoginControl);
        stIn.szSaveFileName = deviceLoginControl.getVideoStoragePath() + new SimpleDateFormat("YYYYMMddHHmmssSSS").format(new Date()) + ".flv";   // 转换后的裸H264码流文件名
        // 创建Stout对象
        NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE stOut = new NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE();
        // 预览转码流保存
        NetSDKLib.LLong lRealHandle = deviceLoginControl.netsdk.CLIENT_RealPlayByDataType(deviceLoginControl.m_hLoginHandle, stIn, stOut, 5000);
        if (lRealHandle.longValue() != 0) {
//            System.out.println(Res.string().getAttach());
            System.out.println("RealPlayByDataType Succeed!");
        } else {
            throw new RuntimeException("录像失败.{}");
        }
        try {
            // 录像时间 单位毫秒
            Thread.sleep(deviceLoginControl.getCycleTime());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 停止预览
        deviceLoginControl.netsdk.CLIENT_StopRealPlay(lRealHandle);   // 必须停止拉流后,才会生成文件
    }

    public static void videoRecording(Long cycleTime, String savePath, DeviceLoginControl deviceLoginControl) {
        NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE stIn = new NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE();
        stIn.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_GBPS;
        stIn.nChannelID = 0;
        stIn.rType = NetSDKLib.NET_RealPlayType.NET_RType_Realplay;
        stIn.dwUser = null;
        stIn.szSaveFileName = savePath + new SimpleDateFormat("YYYYMMddHHmmssSSS").format(new Date()) + ".flv";   // 转换后的裸H264码流文件名
        // 创建Stout对象
        NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE stOut = new NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE();
        // 预览转码流保存
        NetSDKLib.LLong lRealHandle = deviceLoginControl.netsdk.CLIENT_RealPlayByDataType(deviceLoginControl.m_hLoginHandle, stIn, stOut, 5000);
        if (lRealHandle.longValue() != 0) {
            System.out.println("RealPlayByDataType Succeed!");
        } else {
            throw new RuntimeException("录像失败.{}");
        }
        try {
            // 录像时间 单位毫秒
            Thread.sleep(cycleTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 停止预览
        deviceLoginControl.netsdk.CLIENT_StopRealPlay(lRealHandle);   // 必须停止拉流后,才会生成文件
    }

    public static void main(String[] args) throws FileNotFoundException {
        DeviceLoginControl deviceLoginControl = new DeviceLoginControl();
        deviceLoginControl.login("ip", 37777, "username", "password");
        videoRecording(300000l, "", deviceLoginControl);
    }
}

DeviceContext

import com.netsdk.api.DeviceLoginControl;
import com.netsdk.common.Res;
import com.netsdk.common.SavePath;
import com.netsdk.lib.NetSDKLib;
import com.sun.jna.Pointer;
import com.web.device.manage.entity.CameraDeviceEntity;
import com.web.device.manage.service.CameraDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Slf4j
@Component
public class DeviceContext {
    @Resource
    private CameraDeviceService cameraDeviceService;

    private Map<String, DeviceLoginControl> deviceLogin = new ConcurrentHashMap<>();

    /**
     * 初始化登录与重连
     */
    @PostConstruct
    private void init() {
        List<CameraDeviceEntity> list = cameraDeviceService.list();
        Map<String, List<CameraDeviceEntity>> collect = list.stream().collect(Collectors.groupingBy(CameraDeviceEntity::getIp));
        for (CameraDeviceEntity cameraDevice : list) {
            DeviceLoginControl deviceLoginControl = new DeviceLoginControl(new DisConnect(), new HaveReConnect());
            if (loginRetry(cameraDevice, deviceLoginControl)) {
                deviceLoginControl.setCycleTime(cameraDevice.getCycleTime());
                deviceLoginControl.setVideoStoragePath(cameraDevice.getVideoStoragePath());
                deviceLoginControl.setCleanCycle(cameraDevice.getCleanCycle());
                deviceLogin.put(cameraDevice.getIp(), deviceLoginControl);
            }
        }
    }

    private boolean loginRetry(CameraDeviceEntity cameraDevice, DeviceLoginControl deviceLoginControl) {
        boolean login = deviceLoginControl.login(cameraDevice.getIp(), cameraDevice.getTcpPort(), cameraDevice.getLoginName(), cameraDevice.getPassword());
        if (!login) {
            log.error("{},正在尝试重连", cameraDevice.getIp());
            int count = 0;
            while (!deviceLoginControl.login(cameraDevice.getIp(), cameraDevice.getTcpPort(), cameraDevice.getLoginName(), cameraDevice.getPassword())) {
                count++;
                log.error("重连 第{}次,请检查网络或设备是否在线.{}", count, cameraDevice.getIp());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    log.error("重连等待异常.{}", cameraDevice.getIp());
                    e.printStackTrace();
                }
                if (count >= 5) {
                    log.error("长时间重连失败,取消重连,请检查网络或设备是否在线.{}", cameraDevice.getIp());
                    return false;
                }
            }
            log.info("重连成功.{}", cameraDevice.getIp());
        }
        return true;
    }

    @Scheduled(fixedDelay = 300000)
    public void initDevice() {
        List<CameraDeviceEntity> list = cameraDeviceService.list();
        list.forEach(f -> {
            if (!deviceLogin.containsKey(f.getIp()) && !deviceLogin.containsKey("DisConnect-" + f.getIp())) {
                DeviceLoginControl deviceLoginControl = new DeviceLoginControl(new DisConnect(), new HaveReConnect());
                if (loginRetry(f, deviceLoginControl)) {
                    deviceLoginControl.setCycleTime(f.getCycleTime());
                    deviceLoginControl.setVideoStoragePath(f.getVideoStoragePath());
                    deviceLoginControl.setCleanCycle(f.getCleanCycle());
                    deviceLogin.put(f.getIp(), deviceLoginControl);
                }
            }
        });

    }

    public Map<String, DeviceLoginControl> getDeviceLogin() {
        return deviceLogin;
    }

    public 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();
                }
            }
        }
    }

    public class DisConnect implements NetSDKLib.fDisConnect {
        /**
         * 断线回调
         *
         * @param m_hLoginHandle
         * @param pchDVRIP
         * @param nDVRPort
         * @param dwUser
         */
        public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
            if (deviceLogin.containsKey(pchDVRIP)) {
                synchronized (deviceLogin) {
                    if (deviceLogin.containsKey(pchDVRIP)) {
                        DeviceLoginControl deviceLoginControl = deviceLogin.get(pchDVRIP);
                        deviceLogin.remove(pchDVRIP);
                        deviceLogin.put("DisConnect-" + pchDVRIP, deviceLoginControl);
                    }
                }
            }
            Res.string().getDisConnectReconnecting();
        }
    }

    private 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);
            if (deviceLogin.containsKey("DisConnect-" + pchDVRIP)) {
                synchronized (deviceLogin) {
                    if (deviceLogin.containsKey("DisConnect-" + pchDVRIP)) {
                        DeviceLoginControl deviceLoginControl = deviceLogin.get("DisConnect-" + pchDVRIP);
                        deviceLogin.remove("DisConnect-" + pchDVRIP);
                        deviceLogin.put(pchDVRIP, deviceLoginControl);
                    }
                }
            }
            Res.string().getOnline();
        }
    }
}

调用的接口

package com.web.device.manage.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.netsdk.api.DeviceLoginControl;
import com.netsdk.api.PtzControl;
import com.netsdk.lib.NetSDKLib;
import com.web.common.constant.WebConstant;
import com.web.common.entity.web.Failure;
import com.web.common.entity.web.Result;
import com.web.common.utils.BeanUtils;
import com.web.common.web.BaseController;
import com.web.device.manage.DeviceContext;
import com.web.device.manage.entity.CameraDeviceEntity;
import com.web.device.manage.model.response.CameraDeviceResponseModel;
import com.web.device.manage.service.CameraDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping(WebConstant.RequestMappingConstant.CAMERA_DEVICE)
public class CameraDeviceController extends BaseController {
    @Resource
    private CameraDeviceService cameraDeviceService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private DeviceContext deviceContext;

    @RequestMapping(WebConstant.RequestMappingConstant.LIST)
    public Result list() {
        return executor(e -> {
            List<CameraDeviceEntity> cameraDevices = cameraDeviceService.list();
            e.put("cameraDevices", BeanUtils.convertListToList(cameraDevices, new TypeReference<List<CameraDeviceResponseModel>>() {
            }));
        }, f -> Failure.instance(WebConstant.Code.ERROR, f.getMessage()));
    }

    @RequestMapping("/download")
    public void download(@RequestBody Map<String, String> params, HttpServletResponse response) {
        try {
            // path是指想要下载的文件的路径
            File file = new File(params.get("path"));
            log.info(file.getPath());
            // 获取文件名
            String filename = file.getName();
            // 获取文件后缀名
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
            log.info("文件后缀名:" + ext);

            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(params.containsKey("name") ? params.get("name") : new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + "." + ext, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @RequestMapping(WebConstant.RequestMappingConstant.SET_CLEAN_CYCLE)
    public Result setCleanCycle(@PathVariable("cycle") Integer cycle) {
        return executor(e -> {
            redisTemplate.opsForValue().set("cleanCycle", cycle);
        }, f -> Failure.instance(WebConstant.Code.ERROR, f.getMessage()));
    }

    @RequestMapping(WebConstant.RequestMappingConstant.GET_CLEAN_CYCLE)
    public Result getCleanCycle() {
        return executor(e -> {
            Object cleanCycle = redisTemplate.opsForValue().get("cleanCycle");
            if (cleanCycle == null) {
                redisTemplate.opsForValue().set("cleanCycle", 7);
                e.put("cycle", 7);
            } else {
                e.put("cycle", cleanCycle);
            }
        }, f -> Failure.instance(WebConstant.Code.ERROR, f.getMessage()));
    }

    @RequestMapping(WebConstant.RequestMappingConstant.PTZ_CONTROL)
    public Result ptzControl(@RequestBody Map<String, Object> params) {
        return executor(e -> {
            Map<String, DeviceLoginControl> deviceLogin = deviceContext.getDeviceLogin();
            DeviceLoginControl deviceLoginControl = deviceLogin.get(params.get("deviceIp"));
            if (!PtzControl.ptzControlStart(deviceLoginControl.getM_hLoginHandle(), (Integer) params.get("type"))) {
                throw new RuntimeException("控制失败");
            }
            Thread.sleep(500);
            if (!PtzControl.ptzControlEnd(deviceLoginControl.getM_hLoginHandle(), (Integer) params.get("type"))) {
                throw new RuntimeException("控制失败");
            }
        }, f -> Failure.instance(WebConstant.Code.ERROR, f.getMessage()));
    }


}

注意

libs的加载地址要指定
在这里插入图片描述

码云地址

dahua-device

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/234944.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小模型学习(1)-人脸识别

【写作背景】因为最近一直在研究大模型&#xff0c;在与客户进行交流时&#xff0c;如果要将大模型的变革性能力讲清楚&#xff0c;就一定要能将AI小模型的一些原理和效果讲清楚&#xff0c;进而形成对比。当然这不是一件简单的事情&#xff0c;一方面大模型分析问题的的本质原…

Flask和Vue框架实现WebSocket消息通信

1 安装环境 1.1 安装Flask环境 主要的安装包 Flask、Flask-SocketIO&#xff0c;注意Python版本要求3.6 # Flask-SocketIO参考地址 https://flask-socketio.readthedocs.io/en/latest/ https://github.com/miguelgrinberg/flask-socketio更新基础环境 # 更新pip python -m …

JVM垃圾回收

文章目录 垃圾回收四种引用引用计数算法可达性分析算法 垃圾回收算法标记清除标记整理复制 分代回收GCGC相关参数GC分析大对象 垃圾回收器串行吞吐量优先响应时间优先 垃圾回收 四种引用 强引用 new创建一个对象&#xff0c;通过等号运算符赋值给一个变量&#xff0c;那么这个…

Vue3中的defineModel

目录 一、vue3的defineModel介绍 二、defineModel使用 &#xff08;1&#xff09;在vite.config.js中开启 &#xff08;2&#xff09;子组件 &#xff08;3&#xff09;父组件 一、vue3的defineModel介绍 为什么要使用到defineModel呢&#xff1f;这里有这样一种场景&…

Java设计模式分类

java的设计模式大体上分为三大类&#xff1a; 创建型模式&#xff08;5种&#xff09;&#xff1a;工厂方法模式&#xff0c;抽象工厂模式&#xff0c;单例模式&#xff0c;建造者模式&#xff0c;原型模式。 结构型模式&#xff08;7种&#xff09;&#xff1a;适配器模式&am…

vue3中关于echars的使用

今天介绍一个好用的插件echars&#xff0c;一个可视化插件Apache ECharts 一、使用步骤 1、安装 npm install echarts --save 2、导入 import * as echarts from echarts 3、正式使用 echars的使用非常的简单&#xff0c;直接点击官网有现成的代码的可用 代码示例 <t…

【Spring教程24】Spring框架实战:从零开始学习SpringMVC 之 SpringMVC入门案例代码示例

目录 1:创建Maven项目&#xff0c;并导入对应的jar包2:创建控制器类3:创建配置类4:创建Tomcat的Servlet容器配置类5:配置Tomcat环境6:启动运行项目7:浏览器访问8:知识点总结 欢迎大家回到《Java教程之Spring30天快速入门》&#xff0c;本教程所有示例均基于Maven实现&#xff0…

FFmpeg抽取视频h264数据重定向

根据视频重定向技术解析中的 截获解码视频流的思路&#xff0c;首先需要解决如何输出视频码流的问题。 目前只针对h264码流进行获取&#xff0c;步骤如下&#xff1a; 打开mp4文件并创建一个空文件用于存储H264数据 提取一路视频流资源 循环读取流中所有的包(AVPacket),为…

2023团体程序设计天梯赛——模拟赛和总决赛题

M-L1-1 嫑废话上代码 Linux 之父 Linus Torvalds 的名言是&#xff1a;“Talk is cheap. Show me the code.”&#xff08;嫑废话&#xff0c;上代码&#xff09;。本题就请你直接在屏幕上输出这句话。 输入格式&#xff1a; 本题没有输入。 输出格式&#xff1a; 在一行中输出…

Docker Compose(容器编排)——9

目录 什么是 Docker Compose生活案例为什么要 Docker ComposeDocker Compose 的安装Docker Compose 的功能Docker Compose 使用场景Docker Compose 文件&#xff08;docker-compose.yml&#xff09; 文件语法版本文件基本结构及常见指令Docker Compose 命令清单 命令清单如下命…

【网络奇缘系列】计算机网络|数据通信方式|数据传输方式

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 这篇文章是关于计算机网络中数据通信的基础知识点&#xff0c; 从模型&#xff0c;术语再到数据通信方式&#…

C++面试宝典第4题:合并链表

题目 有一个链表&#xff0c;其节点声明如下&#xff1a; struct TNode {int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {} }; 现给定两个按升序排列的单链表pA和pB&#xff0c;请编写一个函数&#xff0c;实现这两个单链表的合并。合并后&#xff0c;…

SqlServer中,数字-null的问题

一、业务描述 叫货单&#xff0c;已知叫货金额&#xff0c;填写本次付款金额&#xff0c;计算待付款金额 二、问题 在计算待付款金额时&#xff0c;偶尔会出现待付款金额为空的情况&#xff0c;百思不得其解 三、解决 仔细检查&#xff0c;发现了猫腻。 简单的说&#xff…

前端开发tips

前端开发tips 关于package.json里面&#xff0c;尖角号&#xff08;^&#xff09;和波浪线&#xff08;~&#xff09;的区别 在package.json里面&#xff0c;我们可以使用尖角号&#xff08;^&#xff09;和波浪线&#xff08;~&#xff09;来表示不同的包版本。这些符号通常被…

gin投票系统3

对应视频v1版本 1.优化登陆接口 将同步改为异步 原login前端代码&#xff1a; <!doctype html> <html lang"en"> <head><meta charset"utf-8"><title>香香编程-投票项目</title> </head> <body> <m…

[GPT]Andrej Karpathy微软Build大会GPT演讲(上)--GPT如何训练

前言 OpenAI的创始人之一,大神Andrej Karpthy刚在微软Build 2023开发者大会上做了专题演讲:State of GPT(GPT的现状)。 他详细介绍了如何从GPT基础模型一直训练出ChatGPT这样的助手模型(assistant model)。作者不曾在其他公开视频里看过类似的内容,这或许是OpenAI官方…

在javaweb项目中resource目录和webapp目录的区别

resource存放的是一些配置文件&#xff0c;这些文件一般都是与java代码相关的配置文件&#xff0c;比如这里的jdbc配置文件,在java中可以使用这个目录下的文件&#xff0c;不用写全路径 webapp存放的是web的资源文件&#xff0c;如jsp,html,css&#xff0c;js文件,在网页请求会…

〖大前端 - 基础入门三大核心之JS篇㊿〗- 面向对象之对象的方法、遍历、深浅克隆

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

基于Java Swing泡泡龙游戏(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

javaSwing酒店管理

一、介绍 在这篇博客中&#xff0c;我们将介绍一个基于MySQL数据库、Java编程语言和Swing图形用户界面的简单酒店管理系统。该系统包括了查询房客信息、查询房客状态、修改房客信息、添加房间信息、添加住户、退房管理、预定管理、退订管理、入账管理、出账管理、修改资料等多…