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

news2024/11/26 2:27:57

文章目录

  • 简介
  • 环境要求
  • 库加载问题及解决方法
  • 大华摄像头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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Git进行版本控制

参考&#xff1a;《Python编程从入门到实践》 前言1、安装、配置 Git1.1 在Linux系统中安装Git1.2 在OS X系统中安装Git1.3 在Windows系统中安装Git1.4 配置Git 2、创建项目3、忽略文件4、初始化仓库5、检查状态6、将文件加入到仓库中7、执行提交8、查看提交历史 前言 版本控制…

计算机毕业设计 SpringBoot的乐乐农产品销售系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

stu05-前端的几种常用开发工具

前端的开发工具有很多&#xff0c;可以说有几十种&#xff0c;包括记事本都可以作为前端的开发工具。下面推荐的是常用的几种前端开发工具。 1.DCloud HBuilder&#xff08;轻量级&#xff09; HBuilder是DCloud&#xff08;数字天堂&#xff09;推出的一款支持HTML5的web开发…

HCIP---RSTP/MSTP

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 STP协议虽然能够解决环路问题&#xff0c;但是收敛速度慢&#xff0c;影响了用户通信质量。IEEE于2001年发布的802.1w标准定义了快速生成树协议RSTP&#xff08;Rapid Spanning-Tree Proto…

309. 买卖股票的最佳时机含冷冻期(leetcode) 动态规划思想

文章目录 前言一、题目分析二、算法原理1.状态表示2.状态转移方程3.初始化边界条件4.填表顺序5.返回值是什么 三、代码实现总结 前言 在本文章中&#xff0c;我们将要详细介绍一下Leetcode中买卖股票的最佳时机含冷冻期相关的内容&#xff0c;本题采用动态规划的思想解决 一、…

Android Studio Gradle下载慢解决方法

Android Studio Gradle下载慢解决方法 最近在练习模型部署&#xff0c;主要是在手机端部署&#xff0c;所以使用到了Android Studio&#xff0c;但是在创建项目的时候&#xff0c;一致在下载gradle&#xff0c;而且网速还很慢&#xff0c;不对&#xff0c;是极慢哪种&#xff0…

研表究明,文字的序顺并不定一能响影GPT-4读阅

深度学习自然语言处理 原创作者&#xff1a;yy 很多年前&#xff0c;你一定在互联网上看过这张图&#xff0c;展示了人脑能够阅读和理解打乱顺序的单词和句子&#xff01;而最近东京大学的研究发现&#xff0c;大语言模型&#xff08;LLMs&#xff09; 尤其是 GPT-4&#xff0c…

【设计模式--创建型--原型模式】

设计模式--创建型--原型模式 原型模式概述结构实现结果 案例代码结果使用场景 扩展&#xff08;深\浅克隆&#xff09;浅克隆演示&#xff1a;结果&#xff1a;使用深克隆&#xff08;利用对象流&#xff09;结果 原型模式 概述 用一个已经创建的实例作为原型&#xff0c;通过…

【MySQL】MySQL库的操作

MySQL库的操作 一、创建数据库创建数据库案例字符集和校验规则校验规则对数据库的影响 二、操纵数据库1、查看数据库2、查看当前正在使用的数据库3、使用数据库4、显示创建语句5、数据库删除6、数据库的修改7、备份和恢复8、查看连接情况 一、创建数据库 创建数据库的语法如下…

使用python绘制现有彩票记录走势图

在数据分析和可视化的领域中&#xff0c;彩票走势图是一个经典的例子&#xff0c;它可以展示彩票数字随时间的出现频率和趋势。这里使用英国使用EuroMillions彩票的历史数据作为示例&#xff0c;使用Python和Matplotlib库来创建一个简单的走势图。可以在以下网站搜索.csv文件。…

基于SSM的剧本杀预约系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Promise与async/await的简单介绍

在 JavaScript 中&#xff0c;处理异步操作一直是开发者们面临的挑战之一。传统的回调函数方式往往导致代码难以维护、可读性差、易产生回调地狱等问题。为了解决这些问题&#xff0c;出现了 Promise 和 Async/Await 这两种处理异步操作的方式。 一、异步产生问题示例 当我们…

6.4 U-boot 移植

一、ST 官方 U-boot 编译测试 1. ST 官方 uboot 源码打补丁 1.1 获得 ST 官方的 uboot 源码 https://www.cnblogs.com/toutiegongzhu/p/17578847.html 这里可以看如何下载uboot源码。解压完后输入以下命令&#xff1a; cd stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/s…

什么是图片懒加载(image lazy loading)?它的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

区块链媒体宣发:揭示优势与趋势,引领信息传播新时代

在数字化潮流中&#xff0c;区块链技术正以惊人的速度改变着传媒行业的格局。从区块链媒体宣发中获得的种种优势和未来的趋势&#xff0c;不仅为企业带来了新的推广途径&#xff0c;也在信息传播领域掀起了一场革命。本文将深入探讨区块链媒体宣发的优势以及未来的发展趋势。 1…

一款基于ESP32的迷你四足机器人

一、软件介绍 增加自定义动作模式&#xff0c;可以在小程序中自定义一个最多10个步骤的动作。 附件中&#xff1a;带自定模式固件bin.zip esp32c3固件文件 烧录下图设置 无串口版本esp32c3开发板烧录前先按住BOOT键再插线进入烧录模式&#xff0c;LoadMode选择USB。 二、AP…

计算机毕业设计 SpringBoot的医院门诊在线挂号系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

shiro反序列化漏洞复现

shiro反序列化漏洞复现 文章目录 shiro反序列化漏洞复现版本安装环境漏洞利用流量分析 版本 550 仅需要一个url 721 需要一个账号 安装环境 先配置国内源 安装docker apt-get install docker 安装docker-compose apt-get install docker-compose 拉取镜像 docker pull …

二分查找|滑动窗口|前缀和|LeetCode209: 长度最小的子数组

长度最短的子数组 作者推荐 【动态规划】【广度优先】LeetCode2258:逃离火灾 本文涉及的基础知识点 二分查找算法合集 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 滑动窗口 题目 给定一个含有 n 个正整数的数组和一个正整数 target…

Python开发运维:Python项目发布到K8S集群

目录 一、实验 1.Python项目发布到K8S集群 一、实验 1.Python项目发布到K8S集群 &#xff08;1&#xff09;获取应用程序代码 #把hello-python.tar.gz压缩包上传到k8s控制节点master1的root下&#xff0c;手动解压 tar zxvf hello-python.tar.gz &#xff08;2&#xff0…