文章目录

  • 简介
  • 环境要求
  • 库加载问题及解决方法
  • 大华摄像头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@Datapublic 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 chnlist = new Vector();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; //登录请求响应超时时间设置为5Sint 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默认1000msnetsdk.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 " />

云台控制

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;@Slf4jpublic 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() {@Overridepublic 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@Componentpublic class DeviceContext {@Resourceprivate CameraDeviceService cameraDeviceService;private Map deviceLogin = new ConcurrentHashMap();/** * 初始化登录与重连 */@PostConstructprivate void init() {List list = cameraDeviceService.list();Map<String, List> 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 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 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 {@Resourceprivate CameraDeviceService cameraDeviceService;@Resourceprivate RedisTemplate redisTemplate;@Resourceprivate DeviceContext deviceContext;@RequestMapping(WebConstant.RequestMappingConstant.LIST)public Result list() {return executor(e -> {List cameraDevices = cameraDeviceService.list();e.put("cameraDevices", BeanUtils.convertListToList(cameraDevices, new TypeReference<List>() {}));}, f -> Failure.instance(WebConstant.Code.ERROR, f.getMessage()));}@RequestMapping("/download")public void download(@RequestBody Map 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();// 清空responseresponse.reset();// 设置response的Headerresponse.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 params) {return executor(e -> {Map 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