diff --git a/lib/Lincseek/win/IRNetSDK.dll b/lib/Lincseek/win/IRNetSDK.dll new file mode 100644 index 0000000..c92af5b Binary files /dev/null and b/lib/Lincseek/win/IRNetSDK.dll differ diff --git a/lib/Lincseek/win/IRNetSDK64.dll b/lib/Lincseek/win/IRNetSDK64.dll new file mode 100644 index 0000000..ecc8f93 Binary files /dev/null and b/lib/Lincseek/win/IRNetSDK64.dll differ diff --git a/lib/Lincseek/win/concrt140.dll b/lib/Lincseek/win/concrt140.dll new file mode 100644 index 0000000..9e3d112 Binary files /dev/null and b/lib/Lincseek/win/concrt140.dll differ diff --git a/lib/Lincseek/win/mfc140.dll b/lib/Lincseek/win/mfc140.dll new file mode 100644 index 0000000..90d42d5 Binary files /dev/null and b/lib/Lincseek/win/mfc140.dll differ diff --git a/lib/Lincseek/win/msvcp140.dll b/lib/Lincseek/win/msvcp140.dll new file mode 100644 index 0000000..977de10 Binary files /dev/null and b/lib/Lincseek/win/msvcp140.dll differ diff --git a/lib/Lincseek/win/vcruntime140.dll b/lib/Lincseek/win/vcruntime140.dll new file mode 100644 index 0000000..809a907 Binary files /dev/null and b/lib/Lincseek/win/vcruntime140.dll differ diff --git a/pom.xml b/pom.xml index f05eb89..4c35455 100644 --- a/pom.xml +++ b/pom.xml @@ -101,13 +101,6 @@ - - net.java.jna - jna - 1.0.0 - compile - - net.java.examples examples diff --git a/src/main/java/com/inspect/nvr/config/LincseekConfig.java b/src/main/java/com/inspect/nvr/config/LincseekConfig.java new file mode 100644 index 0000000..8542ebe --- /dev/null +++ b/src/main/java/com/inspect/nvr/config/LincseekConfig.java @@ -0,0 +1,77 @@ +package com.inspect.nvr.config; + +import com.inspect.nvr.jna.lincseek.IRNetSDK; +import com.inspect.nvr.jna.lincseek.IRNetSDKStruct.IRNETHANDLE; +import com.sun.jna.DefaultTypeMapper; +import com.sun.jna.FromNativeContext; +import com.sun.jna.FromNativeConverter; +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.ToNativeContext; +import com.sun.jna.TypeConverter; +import com.sun.jna.win32.W32APIFunctionMapper; +import com.sun.jna.win32.W32APITypeMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * 朗驰SDK初始化 + */ +@Configuration +@Component +@Slf4j +public class LincseekConfig { + + @Bean + public IRNetSDK initSDK() { + // 自定义 TypeMapper:将 native Pointer 转换为 IRNETHANDLE + DefaultTypeMapper mergedMapper = new DefaultTypeMapper() { + @Override + public FromNativeConverter getFromNativeConverter(Class javaType) { + FromNativeConverter c = super.getFromNativeConverter(javaType); + if (c != null) return c; + return W32APITypeMapper.DEFAULT.getFromNativeConverter(javaType); + } + }; + mergedMapper.addTypeConverter(IRNETHANDLE.class, new TypeConverter() { + @Override + public Object fromNative(Object nativeValue, FromNativeContext context) { + if (nativeValue == null) return null; + long peer = Pointer.nativeValue((Pointer) nativeValue); + return new IRNETHANDLE(peer); + } + + @Override + public Object toNative(Object value, ToNativeContext context) { + return value; + } + + @Override + public Class nativeType() { + return Pointer.class; + } + }); + + Map options = new HashMap<>(); + options.put(Library.OPTION_TYPE_MAPPER, mergedMapper); + options.put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII); + + IRNetSDK irNetSDK = Native.load( + System.getProperty("user.dir") + "\\lib\\Lincseek\\win\\IRNetSDK64", + IRNetSDK.class, options); + int ret = irNetSDK.IRNET_ClientStartup(0, null, null, null, null); + if (ret != 1) { + log.error("[朗驰]SDK启动失败"); + return null; + } + log.info("[朗驰]SDK已初始化"); + return irNetSDK; + } + +} diff --git a/src/main/java/com/inspect/nvr/config/SdkCleanup.java b/src/main/java/com/inspect/nvr/config/SdkCleanup.java index c7b93c5..d1370cd 100644 --- a/src/main/java/com/inspect/nvr/config/SdkCleanup.java +++ b/src/main/java/com/inspect/nvr/config/SdkCleanup.java @@ -2,8 +2,10 @@ package com.inspect.nvr.config; import com.inspect.nvr.daHuaCarme.jna.NetSDKLib; import com.inspect.nvr.hikVision.utils.jna.HCNetSDK; +import com.inspect.nvr.jna.lincseek.IRNetSDK; import com.inspect.nvr.service.DahuaLoginService; import com.inspect.nvr.service.HikLoginService; +import com.inspect.nvr.service.LincseekLoginService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -27,16 +29,23 @@ public class SdkCleanup { @Resource private DahuaLoginService dahuaLoginService; + @Resource + private IRNetSDK irNetSDK; + @Resource + private LincseekLoginService lincseekLoginService; + @PreDestroy public void cleanup() { log.info("JVM shutting down, cleaning up SDK resources..."); // 注销所有登录句柄 hikLoginService.logoutAll(); dahuaLoginService.logoutAll(); + lincseekLoginService.logoutAll(); log.info("已注销所有登录句柄"); // 释放SDK全局资源 hcNetSDK.NET_DVR_Cleanup(); dhNetSDK.CLIENT_Cleanup(); + irNetSDK.IRNET_ClientCleanup(); log.info("已释放所有SDK资源"); } } diff --git a/src/main/java/com/inspect/nvr/controller/CameraController.java b/src/main/java/com/inspect/nvr/controller/CameraController.java index e44d647..ef9f125 100644 --- a/src/main/java/com/inspect/nvr/controller/CameraController.java +++ b/src/main/java/com/inspect/nvr/controller/CameraController.java @@ -7,8 +7,10 @@ import com.inspect.nvr.hikVision.utils.AjaxResult; import com.inspect.nvr.service.DahuaService; import com.inspect.nvr.service.HikVisionService; import com.inspect.nvr.service.IvsCameraService; +import com.inspect.nvr.service.LincseekCameraService; import com.inspect.nvr.utils.redis.RedisService; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @@ -29,6 +31,8 @@ public class CameraController { IvsCameraService iVsCameraService; @Resource private RedisService redisService; + @Autowired + private LincseekCameraService lincseekCameraService; //获取相机预置位列表--海康相机 @PostMapping("/hw/cameraYzwHikVision") @@ -42,16 +46,18 @@ public class CameraController { @PostMapping("/hw/cameraHong") @ResponseBody @CrossOrigin - public TemperatureData cameraHong(@RequestBody Camera camera) throws InterruptedException { + public TemperatureData cameraHong(@RequestBody Camera camera) { log.info("红外开始===================================》》》》》"); TemperatureData temperatureData = null; - if(CameraEnum.HIKVISION.getCode() == camera.getCameraType()){ + if (CameraEnum.DAHUA.getCode() == camera.getCameraType()) { + temperatureData = dahuaService.StartRemote(camera); + } else if (CameraEnum.LINCSEEK.getCode() == camera.getCameraType()) { + temperatureData = lincseekCameraService.getTemp(camera); + } else { temperatureData = executeWithTimeout(() -> cameraService.StartRemote(camera), 7, TimeUnit.SECONDS); // temperatureData = cameraService.StartRemote(camera); - } else { - temperatureData = dahuaService.StartRemote(camera); } - String redisKey = camera.getIp() +'_'+ camera.getPresetId(); + String redisKey = camera.getIp() + '_' + camera.getPresetId(); log.info("红外结束, redisKey: {}, temperatureData: {}", redisKey, temperatureData); redisService.setCacheObject(redisKey, temperatureData, 14400L, TimeUnit.SECONDS); return temperatureData; diff --git a/src/main/java/com/inspect/nvr/domain/Infrared/NvrInfo.java b/src/main/java/com/inspect/nvr/domain/Infrared/NvrInfo.java index 8169633..2625f50 100644 --- a/src/main/java/com/inspect/nvr/domain/Infrared/NvrInfo.java +++ b/src/main/java/com/inspect/nvr/domain/Infrared/NvrInfo.java @@ -4,6 +4,7 @@ package com.inspect.nvr.domain.Infrared; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.ToString; import java.util.Date; @@ -11,8 +12,8 @@ import java.util.Date; @Data @AllArgsConstructor @NoArgsConstructor +@ToString public class NvrInfo { - /** id */ private Integer id; /** nvr名称 */ @@ -43,15 +44,12 @@ public class NvrInfo { private Integer startChannel; /** 硬盘数量 */ private Integer calicheNumber; - /** 同步时间 */ private Date syncDate; /** 字符编码格式*/ private Integer charEncodeType; /** 是否删除【0.否 1.是】 */ private Integer isFlag; - - - - + /** 预置位 */ + private Integer preset; } diff --git a/src/main/java/com/inspect/nvr/enums/CameraEnum.java b/src/main/java/com/inspect/nvr/enums/CameraEnum.java index f44d44a..4d1bbfb 100644 --- a/src/main/java/com/inspect/nvr/enums/CameraEnum.java +++ b/src/main/java/com/inspect/nvr/enums/CameraEnum.java @@ -1,21 +1,25 @@ package com.inspect.nvr.enums; +import lombok.Getter; + /** * 相机类型枚举 */ +@Getter public enum CameraEnum { - // 大华 - HIKVISION(0), // 海康威视 - DAHUA(1); + HIKVISION(0), + // 大华 + DAHUA(1), + // 朗驰欣创 + LINCSEEK(2), + // 海康朗驰(海康部分:可见光、云台;朗驰部分:热成像,测温) + // todo 待实现 + HIKLINC(3); - private int code; + final private int code; CameraEnum(int code) { this.code = code; } - - public int getCode() { - return code; - } } diff --git a/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDK.java b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDK.java new file mode 100644 index 0000000..0a05438 --- /dev/null +++ b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDK.java @@ -0,0 +1,1056 @@ +package com.inspect.nvr.jna.lincseek; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinDef.*; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.ShortByReference; +import com.sun.jna.win32.StdCallLibrary; + +/** + * IRNetSDK64.dll (x86: IRNetSDK.dll) 的 JNA 映射。 + *

+ * 所有函数使用 __stdcall 调用约定。{@code IRNETHANDLE} 映射为 Pointer 子类。 + *

+ * + *

快速入门

+ *
{@code
+ * IRNetSDK sdk = IRNetSDK.INSTANCE;
+ *
+ * // 启动SDK
+ * int result = sdk.IRNET_ClientStartup(0, null, null, null, null);
+ *
+ * // 创建连接信息
+ * CHANNEL_CLIENTINFO info = CHANNEL_CLIENTINFO.create(
+ *     "设备名", "admin", "密码", (byte)0, null, null, 0, null, null);
+ *
+ * // 连接设备
+ * IRNETHANDLE handle = sdk.IRNET_ClientStart("192.168.1.100", info, (short)3000, 0);
+ *
+ * // ... 使用SDK功能 ...
+ *
+ * // 清理
+ * sdk.IRNET_ClientStop(handle);
+ * sdk.IRNET_ClientCleanup();
+ * }
+ * + * @see IRNetSDKCallback 回调接口 + * @see IRNetSDKConst 常量和枚举 + * @see IRNetSDKStruct 结构体定义 + */ +@SuppressWarnings({"unused", "SpellCheckingInspection"}) +public interface IRNetSDK extends StdCallLibrary { + + /** 加载 x64 DLL (IRNetSDK64.dll) */ +// IRNetSDK INSTANCE = Native.load(System.getProperty("user.dir") + "\\lib\\Lincseek\\win\\IRNetSDK64", IRNetSDK.class, W32APIOptions.DEFAULT_OPTIONS); + + /** 加载 x86 DLL (IRNetSDK.dll) */ +// IRNetSDK INSTANCE_X86 = Native.load(System.getProperty("user.dir") + "\\lib\\Lincseek\\win\\IRNetSDK", IRNetSDK.class, W32APIOptions.DEFAULT_OPTIONS); + + // ═════════════════════════════════════════════════════════════════════ + // 第一部分:SDK 生命周期 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 初始化SDK,分配SDK资源。 + * @param m_nMessage 应用程序的一个用户自定义消息 + * @param m_hWnd 应用程序的一个窗口句柄 + * @param m_messagecallback 消息回调函数接口 + * @param context 用户上下文 + * @param key 授权字符串(默认NULL) + * @return 1-表示成功,0-表示失败 + * @note 设备连接断开、连接成功等消息,会通过回调函数m_messagecallback异步通知 + * @see IRNET_ClientCleanup + */ + int IRNET_ClientStartup(int m_nMessage, HWND m_hWnd, + IRNetSDKCallback.CCICallback m_messagecallback, + Pointer context, String key); + + /** + * 获取消息。 + * @param m_sername [in/out] 设备名称 + * @param m_url [in/out] 设备IP地址 + * @param m_port [in/out] 设备端口 + * @param m_ch [in/out] 设备通道 + * @param wParam [in/out] 消息左参数 + * @param lParam [in/out] 消息右参数 + * @return 1表示成功,0表示失败 + */ + int IRNET_ClientReadMessage(byte[] m_sername, byte[] m_url, + ShortByReference m_port, IntByReference m_ch, + IntByReference wParam, Pointer lParam); + + /** + * 设置SDK连接设备的超时时间和重试次数。 + * @param m_waitnum 等待时间(秒),默认6 + * @param m_trynum 重试次数,默认3 + * @return TRUE表示成功,FALSE表示失败 + * @attention 不要把m_waitnum的值设置得太小,通过互联网连接时可能会导致连接失败 + */ + boolean IRNET_ClientWaitTime(int m_waitnum, int m_trynum); + + /** + * 卸载客户端SDK,释放SDK资源。 + * @return TRUE表示成功,FALSE表示失败 + * @see IRNET_ClientStartup + */ + boolean IRNET_ClientCleanup(); + + // ═════════════════════════════════════════════════════════════════════ + // 第二部分:连接与视频显示 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 与设备建立连接,并实时预览图像。 + * @param m_url 设备的IP地址(或转发服务器的IP地址) + * @param m_pChaninfo CHANNEL_CLIENTINFO 指针 + * @param wserport 设备(或转发服务器)的端口号 + * @param streamtype 连接的码流类型: 0=主码流, 1=子码流(需要设备支持) + * @return -1表示失败,其他值为连接句柄 + * @see IRNET_ClientStop + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientStart(String m_url, + IRNetSDKStruct.CHANNEL_CLIENTINFO m_pChaninfo, + short wserport, int streamtype); + + /** + * 停止预览,断开与设备的连接。 + * @param hHandle 连接句柄(IRNET_ClientStart的返回值) + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientStop(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** + * 开启图像显示(连接时m_playstart为FALSE时,需手动调用此接口)。 + * @param hHandle 连接句柄 + * @param decodesign 释放解码资源标志:1=释放,0=不释放 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientStartView(IRNetSDKStruct.IRNETHANDLE hHandle, boolean decodesign); + + /** + * 停止图像显示(不断开连接)。 + * @param hHandle 连接句柄 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientStopView(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** + * 设置图像显示的窗口。 + * @param hHandle 连接句柄 + * @param hWnd 图像窗口(仅Windows直接渲染) + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetWnd(IRNetSDKStruct.IRNETHANDLE hHandle, HWND hWnd); + + /** + * 刷新图像显示的窗口。 + * @param hHandle 连接句柄 + * @param rect 需要刷新的区域(NULL表示全窗口) + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientRefrenshWnd(IRNetSDKStruct.IRNETHANDLE hHandle, RECT rect); + + /** + * 设置图像显示延时(缓冲帧数)。 + * @param hHandle 连接句柄 + * @param delaytime 延时时间(帧): 0=实时, 1-100=延时, 值越大延时越大但图像越平滑 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetDelayTime(IRNetSDKStruct.IRNETHANDLE hHandle, int delaytime); + + /** + * 防止图像分裂。 + * @param hHandle 连接句柄 + * @param bsplit 防止分裂标志 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientPreventImageSplit(IRNetSDKStruct.IRNETHANDLE hHandle, boolean bsplit); + + /** + * 获取图像尺寸。 + * @param hHandle 连接句柄 + * @param m_pWidth [out] 图像的宽度 + * @param m_pHeight [out] 图像的高度 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientGetVideoSize(IRNetSDKStruct.IRNETHANDLE hHandle, + IntByReference m_pWidth, IntByReference m_pHeight); + + /** + * 设置是否显示图像。 + * @param hHandle 连接句柄 + * @param bShow TRUE=显示视频, FALSE=不显示 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetImageShow(IRNetSDKStruct.IRNETHANDLE hHandle, boolean bShow); + + /** + * 获取客户端状态。 + * @param hHandle 连接句柄 + * @return 状态码: -1=正在连接, -1000=无效句柄, 0=成功, 1=用户停止, 2=连接失败, + * 3=设备断开, 4=绑定端口失败, 5=内存错误, 6=登录失败, + * -102=用户数限制, -103=设备列表已满, -105=通道用户超限, + * -106=通道无效, -112=未找到服务器 + */ + int IRNET_ClientGetState(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** + * 清理显示缓冲区。 + * @param hHandle 连接句柄 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_CleanVideoDisplayBuffer(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第三部分:回调注册 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 注册视频显示的回调函数(YUV数据回调)。 + * @param hHandle 连接句柄 + * @param ShowCallBack 回调函数 + * @param context 用户上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientShowcallback(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.ShowCallback ShowCallBack, Pointer context); + + /** + * 注册音频解码的回调函数。 + * @param hHandle 连接句柄 + * @param AudioDecCallBack 回调函数 + * @param context 用户上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientAudioDeccallback(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.AudioDecCallback AudioDecCallBack, Pointer context); + + /** + * 注册画图回调函数(基于HDC,仅Windows)。 + * @param hHandle 连接句柄 + * @param DrawCallBack 回调函数 + * @param context 用户上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientDrawCallBack(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.DrawCallback DrawCallBack, Pointer context); + + /** + * 注册图像显示回调(回调方式,基于HDC)。 + * @param hHandle 连接句柄 + * @param DrawCallBack 回调函数 + * @param context 用户上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientShowImageDrawCallback(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.DrawCallback DrawCallBack, Pointer context); + + /** + * 注册测温回调。 + * @param hHandle 连接句柄 + * @param pCallBack 回调函数地址 + * @param tempSpan [in/out] 温跨 + * @param context 自定义上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientRegTempCallBack(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.TempCallback pCallBack, + IRNetSDKStruct.DEV_TEMP_SPAN tempSpan, Pointer context); + + /** + * 注册获取红外通道raw数据回调。 + * @param hHandle 连接句柄 + * @param pFunc 回调函数地址 + * @param context 上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientRegRawCallback(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.RawCallback pFunc, Pointer context); + + // ═════════════════════════════════════════════════════════════════════ + // 第四部分:云台控制 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 控制云台。 + * @param hHandle 连接句柄 + * @param type 云台控制码(见 IRNetSDKConst 中的 PTZ_* 常量) + * @param value 控制参数[1,10] + * @param priority 云台控制优先级(需要设备支持) + * @param extrabuff 需要发给设备的额外数据 + * @param extrasize 额外数据大小 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientPTZCtrl(IRNetSDKStruct.IRNETHANDLE hHandle, + int type, int value, int priority, byte[] extrabuff, int extrasize); + + /** + * 设置云台地址。 + * @param hHandle 连接句柄 + * @param m_ptzaddr 云台地址 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetPTZAddr(IRNetSDKStruct.IRNETHANDLE hHandle, byte m_ptzaddr); + + // ═════════════════════════════════════════════════════════════════════ + // 第五部分:录像与原始数据获取 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 设置预录像。 + * @param hHandle 连接句柄 + * @param m_benable 使能标志 + * @param m_buffsize 缓冲区大小(新版SDK中弃用) + * @param m_framecount 预录像帧数 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientPrerecord(IRNetSDKStruct.IRNETHANDLE hHandle, + boolean m_benable, int m_buffsize, int m_framecount); + + /** + * 获取通道视频音频压缩信息。 + * @param hHandle 连接句柄 + * @param m_pStreamInfo [in/out] VSTREAMINFO结构指针 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientGetStreamInfo(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.VSTREAMINFO m_pStreamInfo); + + /** + * 开始获取原始码流。 + * @param hHandle 连接句柄 + * @param m_nomalvideo 视频数据回调函数 + * @param pvideocontext 视频用户上下文 + * @param m_nomalaudio 音频数据回调函数 + * @param paudiocontext 音频用户上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientStartNomalCap(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.OriginalVideoCallback m_nomalvideo, Pointer pvideocontext, + IRNetSDKCallback.OriginalAudioCallback m_nomalaudio, Pointer paudiocontext); + + /** + * 停止获取原始码流。 + * @param hHandle 连接句柄 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientStopNomalCap(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第六部分:远程配置(消息通道) + // ═════════════════════════════════════════════════════════════════════ + + /** + * 打开远程配置消息通道。 + * @param sername 服务器名称(小于等于24个字符) + * @param url 服务器地址 + * @param username 用户名(小于等于20个字符) + * @param password 密码(小于等于20个字符) + * @param serport 服务器端口号(默认3000) + * @return -1表示失败,其他值为消息通道句柄 + * @attention 接口调用成功后,必须调用IRNET_ClientMessageClose释放资源 + * @see IRNET_ClientMessageOpt, IRNET_ClientMessageClose + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientMessageOpen(String sername, String url, + String username, String password, short serport); + + /** + * 远程配置操作(读写设备参数)。 + * @param hHandle 消息通道句柄 + * @param opt 命令码(见 MessageOpt 常量) + * @param ch 通道号 + * @param param1 [in/out] 参数1(结构体相关) + * @param param2 [in/out] 参数2 + * @param param3 [in/out] 参数3 + * @return 一般 TRUE=成功, FALSE=失败 + */ + int IRNET_ClientMessageOpt(IRNetSDKStruct.IRNETHANDLE hHandle, + int opt, int ch, Pointer param1, Pointer param2, Pointer param3); + + /** + * 关闭远程配置消息通道。 + * @param hHandle 消息通道句柄 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientMessageClose(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第七部分:直接获取温度数据 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 获取温度数据缓冲区。 + * @param m_sername 设备名称 + * @param m_url 设备IP + * @param m_username 用户名 + * @param m_password 密码 + * @param pbuff [out] 数据缓冲区 + * @param wserport 设备端口(默认3000) + * @return >=0=成功(数据长度), <0=失败 + */ + int IRNET_ClientGetTempData(String m_sername, String m_url, + String m_username, String m_password, byte[] pbuff, short wserport); + + /** + * 保存服务器参数到本地。 + * @param m_sername 设备名称 + * @param m_url 设备IP + * @param m_username 用户名 + * @param m_password 密码 + * @param wserport 设备端口 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSaveServerPara(String m_sername, String m_url, + String m_username, String m_password, short wserport); + + // ═════════════════════════════════════════════════════════════════════ + // 第八部分:固件升级 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 开始远程升级设备固件。 + * @param m_url 设备IP + * @param m_username 用户名 + * @param m_password 密码 + * @param m_filename 固件文件路径 + * @param m_hEndEvent 事件句柄(Windows HANDLE) + * @param wserport 设备端口 + * @param m_sername 设备名称 + * @return -1=失败, 其他=升级句柄 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientUpdateStart(String m_url, + String m_username, String m_password, String m_filename, + Pointer m_hEndEvent, short wserport, String m_sername); + + /** + * 停止固件升级并获取结果。 + * @param hHandle 升级句柄 + * @return 0=升级成功, 2=升级失败, -102=用户/密码错误 + */ + int IRNET_ClientUpdateStop(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第九部分:音频 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 设置音频音量。 + * @param hHandle 连接句柄 + * @param m_Volume 音量值 0x0000(静音) - 0xFFFF(最大) + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientAudioVolume(IRNetSDKStruct.IRNETHANDLE hHandle, short m_Volume); + + /** + * 播放音频。 + * @param hHandle 连接句柄 + * @return TRUE表示成功,FALSE表示失败 + * @attention 仅支持Windows平台 + */ + boolean IRNET_ClientPlayAudio(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** + * 停止播放音频。 + * @param hHandle 连接句柄 + * @return TRUE表示成功,FALSE表示失败 + * @attention 仅支持Windows平台 + */ + boolean IRNET_ClientStopAudio(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** + * 开始对讲。 + * @param servername 设备名 + * @param url 设备IP + * @param username 用户名 + * @param password 密码 + * @param serport 端口 + * @param talkcallback 对讲回调 + * @param samplerate 采样率(默认8000) + * @param context 用户上下文 + * @return -1=只能开启一路对讲, -2=音频采集失败, -3=IP无效, -4=不支持的操作系统, >0=有效句柄 + * @attention 仅支持Windows平台 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientTalkStart(String servername, + String url, String username, String password, short serport, + IRNetSDKCallback.TalkCallback talkcallback, int samplerate, Pointer context); + + /** + * 停止对讲。 + * @param talkhandle 对讲句柄 + * @return 1=成功, 0=失败 + * @attention 仅支持Windows平台 + */ + int IRNET_ClientTalkStop(IRNetSDKStruct.IRNETHANDLE talkhandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第十部分:电子放大 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 设置电子放大区域。 + * @param hHandle 连接句柄 + * @param pRect 放大矩形区域(相对于图像: 0,0,width,height) + * @param bEnable 使能控制 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetZoomRect(IRNetSDKStruct.IRNETHANDLE hHandle, + RECT pRect, boolean bEnable); + + /** + * 电子放大移动使能。 + * @param hHandle 连接句柄 + * @param bEnable true=启用, false=关闭 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientElectronicZoomMoveEnable(IRNetSDKStruct.IRNETHANDLE hHandle, boolean bEnable); + + // ═════════════════════════════════════════════════════════════════════ + // 第十一部分:环境与测温配置 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 设置设备测温环境信息(发射率、距离等)。 + * @param hHandle 连接句柄 + * @param devInfo 设备环境信息 + * @param DeviceMode FALSE=使用PC端参数, TRUE=使用设备端参数 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetDevInfo(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.DEV_ENV_INFO devInfo, boolean DeviceMode); + + /** + * 获取设备测温环境信息。 + * @param hHandle 连接句柄 + * @param devInfo [out] 设备环境信息 + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientGetDevInfo(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.DEV_ENV_INFO devInfo, boolean DeviceMode); + + /** + * 设置设备温跨。 + * @param hHandle 连接句柄 + * @param tempSpan 温跨信息 + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetTempSpan(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.DEV_TEMP_SPAN tempSpan, boolean DeviceMode); + + /** + * 获取设备温跨。 + * @param hHandle 连接句柄 + * @param tempSpan [out] 温跨信息 + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientGetTempSpan(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.DEV_TEMP_SPAN tempSpan, boolean DeviceMode); + + /** + * 设置调色板模式。 + * @param hHandle 连接句柄 + * @param enMode 调色板模式(DEV_PALETE_*) + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetPaletteMode(IRNetSDKStruct.IRNETHANDLE hHandle, + int enMode, boolean DeviceMode); + + /** + * 获取调色板模式。 + * @param hHandle 连接句柄 + * @param enMode [out] 调色板模式 + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientGetPaletteMode(IRNetSDKStruct.IRNETHANDLE hHandle, + IntByReference enMode, boolean DeviceMode); + + /** + * 获取设备温度值(已废弃,建议用MessageOpt代替)。 + * @param hHandle 连接句柄 + * @param tempValue [out] 温度值 + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + * @deprecated 此接口废弃,请使用 MESSAGE_CMD_GET_TEMPVALUE_EX 获取 + */ + boolean IRNET_ClientGetTemperatureValue(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.VSNET_TEMP_VALUE tempValue, boolean DeviceMode); + + // ═════════════════════════════════════════════════════════════════════ + // 第十二部分:图像抓图 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 图像抓图。 + * @param hHandle 连接句柄 + * @param type 文件类型: EN_FT_SDK_LCR=0(红外LCR图), EN_FT_SDK_CHANNEL_JPG=1, EN_FT_SDK_CHANNEL_BMP=2 + * @param fileName 文件名(路径+文件名+扩展名) + * @param quality 图像质量(0-100),默认100 + * @param dataAddr [in/out] 图像数据地址(外部分配内存),type为LCR时表示温度数据 + * @param dataSize [in/out] 数据大小(外部传入内存大小),成功后修改为实际数据大小,失败时修改为0 + * @return 抓图错误码(见 EN_CEC_* 常量) + * @attention type为EN_FT_SDK_LCR时,dataAddr表示温度数据 + */ + int IRNET_ClientCapture(IRNetSDKStruct.IRNETHANDLE hHandle, int type, + byte[] fileName, int quality, byte[] dataAddr, IntByReference dataSize); + + /** + * 开启设备JPEG抓图回传(含温度额外数据)。 + * @return -1=失败, 其他=抓图句柄 + * @see IRNET_ClientJpegCapStop + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientJpegCapStart(String m_sername, + String m_url, String m_username, String m_password, short wserport, + IRNetSDKCallback.JpegDataCallback jpegdatacallback, Pointer userdata); + + /** + * 开启设备JPEG抓图回传(不含温度额外数据)。 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientJpegCapStartGeneral(String m_sername, + String m_url, String m_username, String m_password, short wserport, + IRNetSDKCallback.JpegDataCallbackGeneral jpegdatacallback, Pointer userdata); + + /** + * 触发一次设备抓图回传。 + * @param hHandle 抓图句柄 + * @param m_ch 通道 + * @param m_quality JPEG压缩质量(1=最低, 100=最高) + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientJpegCapSingle(IRNetSDKStruct.IRNETHANDLE hHandle, int m_ch, int m_quality); + + /** + * 触发一次设备抓图回传(扩展,可选择类型)。 + * @param hHandle 抓图句柄 + * @param m_ch 通道 + * @param m_quality 质量 + * @param type 抓图类型: 0x1=可见光, 0x10=红外 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientJpegCapSingleEx(IRNetSDKStruct.IRNETHANDLE hHandle, int m_ch, int m_quality, int type); + + /** + * 停止设备JPEG抓图回传。 + * @param hHandle 抓图句柄 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientJpegCapStop(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第十三部分:视频录像 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 开始录像。 + * @param hHandle 连接句柄 + * @param filename 文件名(路径+文件名+扩展名) + * @param filetype 文件类型(RECDT_MP4, RECDT_AVI 等) + * @param framerate 帧率 + * @return TRUE表示成功,FALSE表示失败 + * @attention 仅支持Windows平台 + */ + boolean IRNET_ClientRecordBegin(IRNetSDKStruct.IRNETHANDLE hHandle, + byte[] filename, int filetype, float framerate); + + /** 录像暂停(仅Windows平台)。 */ + boolean IRNET_ClientRecordPause(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** 录像恢复(仅Windows平台)。 */ + boolean IRNET_ClientRecordResume(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** 录像结束(仅Windows平台)。 */ + boolean IRNET_ClientRecordEnd(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第十四部分:图像融合 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 开启图像融合(红外图叠加到可见光图)。 + * @param hMainHandle 红外通道连接句柄 + * @param hSubHandle 可见光通道连接句柄 + * @return TRUE表示成功,FALSE表示失败 + * @attention 仅支持Windows平台 + */ + boolean IRNET_ClientFuseStart(IRNetSDKStruct.IRNETHANDLE hMainHandle, IRNetSDKStruct.IRNETHANDLE hSubHandle); + + /** 停止图像融合(仅Windows平台)。 */ + boolean IRNET_ClientFuseStop(IRNetSDKStruct.IRNETHANDLE hHandle); + + /** + * 设置融合强度。 + * @param hHandle 连接句柄(红外通道) + * @param byStrength 融合强度 0-100 + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetFusionStrength(IRNetSDKStruct.IRNETHANDLE hHandle, byte byStrength, boolean DeviceMode); + + /** 获取融合强度,返回值<0表示失败。 */ + int IRNET_ClientGetFusionStrength(IRNetSDKStruct.IRNETHANDLE hHandle, boolean DeviceMode); + + /** 设置融合图像可见光水平偏移。 */ + boolean IRNET_ClientSetFusionOffsetHorz(IRNetSDKStruct.IRNETHANDLE hHandle, int iOffset, boolean DeviceMode); + + /** 获取融合图像可见光水平偏移。 */ + int IRNET_ClientGetFusionOffsetHorz(IRNetSDKStruct.IRNETHANDLE hHandle, boolean DeviceMode); + + /** 设置融合图像可见光垂直偏移。 */ + boolean IRNET_ClientSetFusionOffsetVert(IRNetSDKStruct.IRNETHANDLE hHandle, int iOffset, boolean DeviceMode); + + /** 获取融合图像可见光垂直偏移。 */ + int IRNET_ClientGetFusionOffsetVert(IRNetSDKStruct.IRNETHANDLE hHandle, boolean DeviceMode); + + /** + * 设置融合视图模式。 + * @param hHandle 连接句柄 + * @param mode EN_MODE_VIS=1(仅可见光), EN_MODE_FUSION=2(融合) + * @param DeviceMode FALSE=PC端, TRUE=设备端 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetFusionViewMode(IRNetSDKStruct.IRNETHANDLE hHandle, int mode, boolean DeviceMode); + + // ═════════════════════════════════════════════════════════════════════ + // 第十五部分:入侵检测(仅Linux) + // ═════════════════════════════════════════════════════════════════════ + + /** 注册入侵检测回调(仅Linux平台)。 */ + boolean IRNET_ClientRegIntrDetectCallback(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.IntrDetectCallback pFuncAddr); + + /** 开始入侵检测(仅Linux平台)。 */ + boolean IRNET_ClientIntrDetectBegin(IRNetSDKStruct.IRNETHANDLE hHandle, int areaUpper); + + /** 结束入侵检测(仅Linux平台)。 */ + boolean IRNET_ClientIntrDetectEnd(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第十六部分:设备校标 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 设备校标。 + * @param info 设备基本信息 + * @param type 校标类型(EN_DCT_*) + * @param filename 文件名(NULL时使用memaddr) + * @param memaddr 内存地址 + * @param memsize 内存大小 + * @param group 组 + * @param context 自定义上下文 + * @param pCallback 完成回调 + * @return -1=失败, >0=成功 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_DevCalib(IRNetSDKStruct.DEVICE_BASE_INFO info, + int type, String filename, byte[] memaddr, int memsize, short group, + Pointer context, IRNetSDKCallback.FinishCallback pCallback); + + // ═════════════════════════════════════════════════════════════════════ + // 第十七部分:RVS服务器(转发视频服务) + // ═════════════════════════════════════════════════════════════════════ + + /** + * 注册转发服务器通道检测回调函数。 + * @param pchancheck 回调函数 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_RVSRegSerCheckCallback(IRNetSDKCallback.RVSChannelCallback pchancheck); + + /** + * 启动转发服务并注册通道。 + * @param m_pRvsInfo 绑定信息 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_RVSStartServer(IRNetSDKStruct.RVSINFOREG m_pRvsInfo); + + /** + * 注册转发通道报警消息回调函数。 + * @param hHandle 通道句柄 + * @param palarmcallback 报警回调 + * @param context 回调函数上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_RVSRegMsgCallback(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.RVSAlarmCallback palarmcallback, Pointer context); + + /** + * 设置服务器ID(用于转发器中的唯一标识)。 + * @param hHandle 通道句柄 + * @param pSerID 服务器ID + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_RVSSetChanServerID(IRNetSDKStruct.IRNETHANDLE hHandle, String pSerID); + + /** + * 开始/停止数据传输。 + * @param hHandle 通道句柄 + * @param bStart TRUE=设备发送数据, FALSE=设备停止发送 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientMediaData(IRNetSDKStruct.IRNETHANDLE hHandle, boolean bStart); + + /** 停止转发服务并注销通道。 */ + boolean IRNET_RVSStopServer(); + + // ═════════════════════════════════════════════════════════════════════ + // 第十八部分:转发器(端口转发) + // ═════════════════════════════════════════════════════════════════════ + + /** + * 设置转发器信息。 + * @param m_pRedirect 转发器配置 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_SetRedirectorInfo(IRNetSDKStruct.IRNET_REDIRECTORINFO m_pRedirect); + + /** + * 启动转发监听。 + * @param m_localAddrIP 本地IP(NULL=SDK自动获取) + * @return 0=成功, 4=绑定端口失败, 5=内存错误 + */ + int IRNET_StartListenClient(String m_localAddrIP); + + /** 停止转发监听。 */ + boolean IRNET_StopListenClient(); + + // ═════════════════════════════════════════════════════════════════════ + // 第十九部分:串口透传(RS232/RS485) + // ═════════════════════════════════════════════════════════════════════ + + /** + * 打开串口透传通道。 + * @param m_sername 设备名称 + * @param m_url 设备地址 + * @param m_username 用户名 + * @param m_password 密码 + * @param iSerialPort 串口号: 0=RS485, 1=RS232 + * @param pSerialInfo 串口参数 + * @param fSerialDataCallBack 串口接收回调函数 + * @param context 用户上下文 + * @param wserport 设备端口 + * @return -1=失败, >0=透传串口句柄 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientSerialStart(String m_sername, + String m_url, String m_username, String m_password, int iSerialPort, + IRNetSDKStruct.VSSERIAL_INFO pSerialInfo, + IRNetSDKCallback.SerialDataCallback fSerialDataCallBack, + Pointer context, short wserport); + + /** 关闭串口透传。 */ + boolean IRNET_ClientSerialStop(IRNetSDKStruct.IRNETHANDLE hSerial); + + /** 通过串口透传发送数据。 */ + boolean IRNET_ClientSerialSendNew(IRNetSDKStruct.IRNETHANDLE hSerial, + byte[] pSendBuff, int BuffSize); + + /** 串口透传接收暂停。 */ + boolean IRNET_ClientSerialRecvPause(IRNetSDKStruct.IRNETHANDLE hSerial); + + /** 串口透传接收恢复。 */ + boolean IRNET_ClientSerialRecvRestart(IRNetSDKStruct.IRNETHANDLE hSerial); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十部分:ROM/Flash 升级 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 上传ROM(非阻塞,通过 IRNET_GetUploadRomRst 查询状态)。 + */ + void IRNET_StartUploadRom(String m_sername, String m_url, String m_username, + String m_password, short m_wserport, String m_szRomPath); + + /** + * 获取ROM上传状态。 + * @return 2=没有上传事件, 1=正在上传, 0=成功, -1=打开ROM文件失败, -2=读取ROM文件失败, + * -3=URL无效, -4=连接失败, -5=登录失败, -6=用户名密码不匹配, -7=线程创建失败 + */ + int IRNET_GetUploadRomRst(); + + /** + * 升级ROM(支持多线程,带回调)。 + * @return -1=失败, 其他=升级句柄 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_UpgradeROM(String m_sername, String m_url, + String m_username, String m_password, short m_wserport, + String m_szRomPath, IRNetSDKCallback.UpRomCallback callback, Pointer userdata); + + /** + * 升级Flash(支持回调)。 + * @return -1=失败, 其他=升级句柄 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_UpgradeFlash(String sername, String url, + String username, String password, short wserport, + String filepath, IRNetSDKCallback.UpFlashCallback callback, Pointer userdata); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十一部分:WiFi 搜索 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 搜索设备附近的WiFi。 + * @param m_sername 设备名 + * @param m_url 设备IP + * @param m_username 用户名 + * @param m_password 密码 + * @param m_pWifiList [out] WiFi SSID列表 + * @param wserport 设备端口 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientWifiSearch(String m_sername, String m_url, + String m_username, String m_password, + IRNetSDKStruct.VSNET_WIFI_SSID_LIST m_pWifiList, short wserport); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十二部分:智能分析 + // ═════════════════════════════════════════════════════════════════════ + + /** 智能分析使能(仅Windows平台)。 */ + boolean IRNET_ClientIntelligentAnalysisEnable(IRNetSDKStruct.IRNETHANDLE hHandle, boolean bEnable); + + // -- 区域屏蔽 -- + int IRNET_ClientIntelligentAnalysisAddShield(IRNetSDKStruct.IRNETHANDLE hHandle); + int IRNET_ClientIntelligentAnalysisGetShield(IRNetSDKStruct.IRNETHANDLE hHandle); + boolean IRNET_ClientIntelligentAnalysisSetShield(IRNetSDKStruct.IRNETHANDLE hHandle, int regionIndex); + boolean IRNET_ClientIntelligentAnalysisDeleteShield(IRNetSDKStruct.IRNETHANDLE hHandle, int regionIndex); + boolean IRNET_ClientIntelligentAnalysisSaveShield(IRNetSDKStruct.IRNETHANDLE hHandle); + + // -- 目标过滤 -- + boolean IRNET_ClientIntelligentAnalysisTargetFilterCallback(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.TargetFilterCallback maxSizeCallback, Pointer maxSizeContext, + IRNetSDKCallback.TargetFilterCallback minSizeCallback, Pointer minSizeContext); + boolean IRNET_ClientIntelligentAnalysisSetMinTargetFilter(IRNetSDKStruct.IRNETHANDLE hHandle, + IntByReference curWidth, IntByReference curHeight); + boolean IRNET_ClientIntelligentAnalysisSetMaxTargetFilter(IRNetSDKStruct.IRNETHANDLE hHandle, + IntByReference curWidth, IntByReference curHeight); + boolean IRNET_ClientIntelligentAnalysisSaveTargetFilter(IRNetSDKStruct.IRNETHANDLE hHandle); + + // -- 警戒线 -- + int IRNET_ClientIntelligentAnalysisAddCordon(IRNetSDKStruct.IRNETHANDLE hHandle, int arrowDir); + int IRNET_ClientIntelligentAnalysisGetCordon(IRNetSDKStruct.IRNETHANDLE hHandle); + boolean IRNET_ClientIntelligentAnalysisSetCordon(IRNetSDKStruct.IRNETHANDLE hHandle, int regionIndex); + boolean IRNET_ClientIntelligentAnalysisCordonDirc(IRNetSDKStruct.IRNETHANDLE hHandle, + boolean isSet, IntByReference cordonDirc); + boolean IRNET_ClientIntelligentAnalysisDeleteCordon(IRNetSDKStruct.IRNETHANDLE hHandle, int regionIndex); + boolean IRNET_ClientIntelligentAnalysisSaveCordon(IRNetSDKStruct.IRNETHANDLE hHandle); + + // -- 智能分析规则(进入区域/离开区域/物品遗留/物品搬移) -- + int IRNET_ClientIntelligentAnalysisAddSmart(IRNetSDKStruct.IRNETHANDLE hHandle, int smartType); + int IRNET_ClientIntelligentAnalysisGetSmart(IRNetSDKStruct.IRNETHANDLE hHandle, int smartType); + boolean IRNET_ClientIntelligentAnalysisSetSmart(IRNetSDKStruct.IRNETHANDLE hHandle, int regionIndex, int smartType); + boolean IRNET_ClientIntelligentAnalysisDeleteSmart(IRNetSDKStruct.IRNETHANDLE hHandle, int regionIndex, int smartType); + boolean IRNET_ClientIntelligentAnalysisSaveSmart(IRNetSDKStruct.IRNETHANDLE hHandle, int smartType); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十三部分:报警输出控制 + // ═════════════════════════════════════════════════════════════════════ + + /** + * 控制报警输出设备。 + * @param hHandle 连接句柄 + * @param devCH 报警通道 + * @param bOn 1=开, 0=关 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientOutPut(IRNetSDKStruct.IRNETHANDLE hHandle, byte devCH, boolean bOn); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十四部分:多边形测温 + // ═════════════════════════════════════════════════════════════════════ + + /** 多边形测温绘制使能。 */ + boolean IRNET_ClientPolygonTempMeasureDrawEnable(IRNetSDKStruct.IRNETHANDLE hHandle, boolean bEnable); + + /** 设置多边形测温索引。 */ + boolean IRNET_ClientPolygonTempMeasureSetIndex(IRNetSDKStruct.IRNETHANDLE hHandle, int index); + + /** 保存多边形测温数据到设备。 */ + boolean IRNET_ClientPolygonTempMeasureSave(IRNetSDKStruct.IRNETHANDLE hHandle); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十五部分:BMP抓图优化 + // ═════════════════════════════════════════════════════════════════════ + + /** + * BMP抓图(优化)。 + * @param hHandle 连接句柄 + * @param m_filename 输出文件名 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientBMPOptimize(IRNetSDKStruct.IRNETHANDLE hHandle, String m_filename); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十六部分:人头检测(人体测温) + // ═════════════════════════════════════════════════════════════════════ + + /** + * 获取人头检测视频尺寸。 + * @param hHandle 连接句柄 + * @param videoWidth [out] 视频宽 + * @param videoHeight [out] 视频高 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientGetHeadDetectionVideoSize(IRNetSDKStruct.IRNETHANDLE hHandle, + IntByReference videoWidth, IntByReference videoHeight); + + /** + * 注册人头检测回调。 + * @param hHandle 通道句柄 + * @param callbackfun 回调函数 + * @param context 自定义上下文 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientHeadDetection(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKCallback.HeadAreaCallback callbackfun, Pointer context); + + /** + * 设置人体测温头部温度阈值(仅Windows平台)。 + * @param hHandle 通道句柄 + * @param threshold 阈值 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetBodyTemperatureThreshold(IRNetSDKStruct.IRNETHANDLE hHandle, float threshold); + + /** + * 设置人体距离校正参数(仅Windows平台)。 + * @param hHandle 通道句柄 + * @param par 校正参数 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientSetBodyDisCorrParam(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.VSNET_TED_CORRECTION_S par); + + /** + * 获取人体距离校正参数(仅Windows平台)。 + * @param hHandle 通道句柄 + * @param par [out] 校正参数 + * @return TRUE表示成功,FALSE表示失败 + */ + boolean IRNET_ClientGetBodyDisCorrParam(IRNetSDKStruct.IRNETHANDLE hHandle, + IRNetSDKStruct.VSNET_TED_CORRECTION_S par); + + // ═════════════════════════════════════════════════════════════════════ + // 第二十七部分:二次标定(测温) + // ═════════════════════════════════════════════════════════════════════ + + /** + * 二次标定开始(TM)。 + * @return -1=失败, 其他=标定句柄 + */ + IRNetSDKStruct.IRNETHANDLE IRNET_ClientSecondCalib4TmStart(String m_sername, + String m_url, String m_username, String m_password, short wserport, + IRNetSDKCallback.SecondCalibTmCallback seccalibcallback, Pointer userdata); + + /** + * 二次标定执行(TM)。 + * @param hHandle 标定句柄 + * @param channel 通道号 + * @param calib_temp 标定温度(℃) + * @return 0=成功, 其他=失败 + */ + int IRNET_ClientSecondCalib4TmDo(IRNetSDKStruct.IRNETHANDLE hHandle, int channel, float calib_temp); + + /** 二次标定结束。 */ + boolean IRNET_ClientSecondCalib4TmStop(IRNetSDKStruct.IRNETHANDLE hHandle); +} diff --git a/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKCallback.java b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKCallback.java new file mode 100644 index 0000000..2a693fa --- /dev/null +++ b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKCallback.java @@ -0,0 +1,181 @@ +package com.inspect.nvr.jna.lincseek; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinDef.HDC; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; + +/** + * IRNetSDK JNA 回调接口映射。 + * 所有回调均使用 __stdcall (WINAPI) 调用约定。 + * 回调在 native 线程上触发——不要在回调内部阻塞或调用 JNA 函数。 + * 注意:回调方法中的句柄参数统一使用 Pointer 而非 IRNETHANDLE, + * 因为 JNA 回调机制的 TypeMapper 不一定能自动转换 Pointer 子类。 + * 若需作为 IRNETHANDLE 使用,调用方可自行 new IRNETHANDLE(peer)。 + */ +public interface IRNetSDKCallback { + + // ─── 连接 / 消息 ──────────────────────────────────────────────────── + + /** + * 客户端通道消息回调函数指针 + */ + @FunctionalInterface + interface CCICallback extends StdCallCallback { + void invoke(Pointer hHandle, int wParam, long lParam, Pointer context); + } + + // ─── 视频显示 ────────────────────────────────────────────────────── + + @FunctionalInterface + interface ShowCallback extends StdCallCallback { + void invoke(Pointer m_y, Pointer m_u, Pointer m_v, + int stridey, int strideuv, int width, int height, Pointer context); + } + + @FunctionalInterface + interface DrawCallback extends StdCallCallback { + void invoke(HDC hdc, Pointer context); + } + + // ─── 音频 ────────────────────────────────────────────────────────── + + @FunctionalInterface + interface AudioDecCallback extends StdCallCallback { + void invoke(Pointer pBuffer, int size, Pointer context); + } + + @FunctionalInterface + interface TalkCallback extends StdCallCallback { + void invoke(Pointer pbuff, int size, Pointer context); + } + + @FunctionalInterface + interface RVSChannelCallback extends StdCallCallback { + int invoke(String sername, String url, short port, String serialno, + byte[] pyhmac, int channels, int alarmInNum, int alarmOutNum, + int ch, boolean bLogin, Pointer hChHandle); + } + + @FunctionalInterface + interface RVSAlarmCallback extends StdCallCallback { + void invoke(Pointer hHandle, int wParam, long lParam, Pointer context); + } + + // ─── 串口 ────────────────────────────────────────────────────────── + + @FunctionalInterface + interface SerialDataCallback extends StdCallCallback { + void invoke(Pointer hSerial, Pointer pRecvDataBuff, int buffSize, Pointer context); + } + + // ─── JPEG抓图 ────────────────────────────────────────────────────── + + @FunctionalInterface + interface JpegDataCallback extends StdCallCallback { + void invoke(Pointer hHandle, int mCh, Pointer pBuffer, int size, + Pointer extraData, Pointer userdata); + } + + @FunctionalInterface + interface JpegDataCallbackGeneral extends StdCallCallback { + void invoke(Pointer hHandle, int mCh, Pointer pBuffer, int size, Pointer userdata); + } + + // ─── 温度 ────────────────────────────────────────────────────────── + + /** + * 测温回调 + * @param hHandle 连接句柄 + * @param fTemperature 温度数据地址(大小为图像宽*高, 单位K) + * @param uWidth 图像宽 + * @param uHeight 图像高 + * @param tempSpan 温跨 + * @param context 用户上下文 + * @see IRNET_ClientRegTempCallBack + */ + @FunctionalInterface + interface TempCallback extends StdCallCallback { + void invoke(Pointer hHandle, Pointer fTemperature, int uWidth, int uHeight, + IRNetSDKStruct.DEV_TEMP_SPAN tempSpan, Pointer context); + } + + @FunctionalInterface + interface RawCallback extends StdCallCallback { + void invoke(Pointer data, int width, int height, Pointer context); + } + + // ─── 视频/音频原始码流 ────────────────────────────────────────────── + + @FunctionalInterface + interface OriginalVideoCallback extends StdCallCallback { + void invoke(Pointer pbuff, int headsize, int datasize, int timetick, + int biskeyframe, Pointer context); + } + + @FunctionalInterface + interface OriginalAudioCallback extends StdCallCallback { + void invoke(Pointer pbuff, int headsize, int datasize, int timetick, + int biskeyframe, Pointer context); + } + + // ─── 入侵检测 ────────────────────────────────────────────────────── + + @FunctionalInterface + interface IntrDetectCallback extends StdCallCallback { + void invoke(Pointer hHandle, + IRNetSDKStruct.LI_INTRUSION_AREA pArea, int areaCount); + } + + @FunctionalInterface + interface TargetFilterCallback extends StdCallCallback { + void invoke(Pointer hHandle, int targetWidth, int targetHeight, Pointer context); + } + + // ─── 人头检测 ────────────────────────────────────────────────────── + + @FunctionalInterface + interface HeadAreaCallback extends StdCallCallback { + void invoke(Pointer handle, IRNetSDKStruct.VSNET_HEADAREA headArea, + int headAreaCnt, Pointer context); + } + + // ─── 二次标定 ────────────────────────────────────────────────────── + + @FunctionalInterface + interface SecondCalibTmCallback extends StdCallCallback { + void invoke(Pointer hHandle, int mCh, int statusCode, Pointer userdata); + } + + // ─── 升级 ────────────────────────────────────────────────────────── + + @FunctionalInterface + interface UpRomCallback extends StdCallCallback { + void invoke(Pointer upromhandle, int upromresult, Pointer userdata); + } + + @FunctionalInterface + interface UpFlashCallback extends StdCallCallback { + void invoke(Pointer upflashhandle, int upflashresult, Pointer userdata); + } + + // ─── 完成回调 ────────────────────────────────────────────────────── + + @FunctionalInterface + interface FinishCallback extends StdCallCallback { + void invoke(int status, String url, String sername, String username, + short wserport, Pointer context); + } + + // ─── 转发器用户校验 ──────────────────────────────────────────────── + + @FunctionalInterface + interface UserCheckCallback extends StdCallCallback { + int invoke(String url, String username, String password); + } + + @FunctionalInterface + interface UserConnectCallback extends StdCallCallback { + int invoke(String sername, int channel, boolean bStart, String userurl, + String username, String password, int transtype, Pointer handle); + } +} diff --git a/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKConst.java b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKConst.java new file mode 100644 index 0000000..99f037d --- /dev/null +++ b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKConst.java @@ -0,0 +1,808 @@ +package com.inspect.nvr.jna.lincseek; + +/** + * IRNetSDK JNA 映射 — 常量、枚举、宏定义。 + * 与 VSNETStructDef.h 及 IRNet.h 中定义对应。 + */ +public interface IRNetSDKConst { + + // ───────────────────────────────────────────────────────────────────── + // 消息类型(CCICallback 中的 wParam)— IRNet.h + // ───────────────────────────────────────────────────────────────────── + int LAUMSG_LINKMSG = 1; // 连接服务器连接消息 + int LAUMSG_ALARM = 4; // 传感器报警 + int LAUMSG_OUTPUTSTATUS = 5; // 报警输出状态 + int LAUMSG_SERVERRECORD = 11; // 服务器录像状态 + int LAUMSG_DISKFULL = 23; // 硬盘满 + int LAUMSG_DISKERROR = 24; // 硬盘错误 + int LAUMSG_ACCESSVIOLATION = 25; // 非法访问 + int LAUMSG_SERSTART = 26; // 服务器启动 + int LAUMSG_SERSTOP = 27; // 服务器停止 + int LAUMSG_UPDATESTREAMINFO = 30; // 更新码流信息 + int LAUMSG_ALARMMSG_GLOBAL_TEMP = 117; // 全局测温报警 + int LAUMSG_ALARMMSG_REGION_TEMP = 118; // 区域测温报警 + int LAUMSG_ALARMMSG_IN = 119; // 报警输入 + int LAUMSG_IR_HIGHT_ALARM = 9001; // 红外高温报警 + int LAUMSG_IR_LOW_ALARM = 9002; // 红外低温报警 + int LAUMSG_ALARMMSG_FIRE = 9003; // 火警 + int LAUMSG_ALARMMSG_TEMPDIFF = 9004; // 温度对比报警 + int LAUMSG_ALARMMSG_ITELLIGENT_ANALYSIS = 9005; // 智能分析 + int LAUMSG_ALARMMSG_BH_SECURITE_FIRE = 9006; // BH安消一体 + int LAUMSG_ALARMMSG_GRIDS_TEMP = 9007; // GRIDS报警 + + // ───────────────────────────────────────────────────────────────────── + // VSNet 报警消息类型 — VSNETStructDef.h + // ───────────────────────────────────────────────────────────────────── + int VSNETALARMMSG_SERSTART = 1; // 服务器启动 + int VSNETALARMMSG_MOTION = 2; // 移动侦测报警 + int VSNETALARMMSG_VIDEOLOST = 3; // 视频丢失报警 + int VSNETALARMMSG_SENSOR = 4; // 传感器报警 + int VSNETALARMMSG_DISKFULL = 5; // 硬盘满报警 + int VSNETALARMMSG_HIDEALARM = 6; // 视频遮挡报警 + int VSNETALARMMSG_SERSTOP = 7; // 服务器停止 + int VSNETALARMMSG_DISKERROR = 8; // 硬盘错误报警(SMART) + int VSNETALARMMSG_ACCESSVIOLATION = 9; // 非法访问 + int VSNETALARMMSG_ANALYSESINGLELINEALARM = 11; // 智能分析单线报警 + int VSNETALARMMSG_ANALYSEDOUBLELINEALARM = 12; // 智能分析双线报警 + int VSNETALARMMSG_ANALYSEREGIONENTRYALARM = 13; // 智能分析进入区域报警 + int VSNETALARMMSG_ANALYSEREGIONEXITALARM = 14; // 智能分析离开区域报警 + int VSNETALARMMSG_ANALYSEHOVERALARM = 15; // 智能分析徘徊区域报警 + int VSNETALARMMSG_NETANOMALYALARM = 16; // 网络异常报警 + int VSNETALARMMSG_NVR_PUSENSOR = 17; // NVR PU传感器报警 + int VSNETALARMMSG_DISKLOST = 18; // 硬盘丢失报警 + int VSNETALARMMSG_ALARM_IN_SHUT = 34; // 传感器报警停止 + int VSNETALARMMSG_SGLINEALARM = 100; // 智能分析警戒线报警 (>=100且<=109, 目前有10条警戒线规则) + int VSNETALARMMSG_NODISK = 110; // 无硬盘 + int VSNETALARMMSG_NET_BROKEN = 111; // 网线断开 + int VSNETALARMMSG_DISKUNHEALTH = 112; // 硬盘不健康 + int VSNETALARMMSG_PLATECHECK = 113; // 车牌检测报警 + int VSNETALARMMSG_FR_NETOFF = 114; // 前端设备网络断开报警 + int VSNETALARMMSG_FR_IPUPDATE = 115; // 前端设备IP地址更新报警 + int VSNETALARMMSG_IPUPDATE = 116; // 设备IP地址更新报警 + int VSNETALARMMSG_GLOBAL_TEMP = 117; // 全局温度报警 + int VSNETALARMMSG_REGION_TEMP = 118; // 区域温度报警 + int VSNETALARMMSG_ALARM_IN = 119; // 报警输入 + int VSNETALARMMSG_IPCONFLICT = 120; // IP冲突 + int VSNETALARMMSG_USBSTATE = 200; // DX USB状态 0:插入 1:拔出 + int VSNETALARMMSG_AUDIOCH = 201; // DX音频通道 + int VSNETALARMMSG_DXSWITCHCH = 202; // DX切换通道 + int VSNETALARMMSG_DVDSTATE = 203; // DX DVD状态 0:插入 1:拔出 + int VSNETALARMMSG_DISPDVDINFO = 204; // DX通知显示DVD信息 + int VSNETALARMMSG_HM_INFRARED = 301; // 红外对射报警 + int VSNETALARMMSG_HM_DEMOLITION = 302; // 防拆报警 + int VSNETALARMMSG_IR_HIGH_TEMPERATURE_ALARM = 401; // 红外高温报警 + int VSNETALARMMSG_IR_LOW_TEMPERATURE_ALARM = 402; // 红外低温报警 + int VSNETALARMMSG_FIRE = 403; // 火警 + int VSNETALARMMSG_TEMPDIFF = 404; // 温度对比报警 + int VSNETALARMMSG_SMART_ANALYSIS = 405; // 智能分析报警 + int VSNETALARMMSG_THRESHOLD = 406; // 阈值报警 + int VSNETALARMMSG_REGION_THRESHOLD = 407; // 区域阈值报警 + int VSNETALARMMSG_FRAME_THRESHOLD = 408; // 帧阈值报警 + int VSNETALARMMSG_BH_SECURITY_FIRE = 409; // 安消一体报警 + int VSNETALARMMSG_GRIDS_TEMP = 410; // 网格温度报警 + + // ───────────────────────────────────────────────────────────────────── + // 录像类型 — VSNETStructDef.h + // ───────────────────────────────────────────────────────────────────── + int HDISK_RECTYPE_HAND = (1 << 0); // 手动 + int HDISK_RECTYPE_TIMER = (1 << 1); // 定时 + int HDISK_RECTYPE_MOTION = (1 << 2); // 移动侦测 + int HDISK_RECTYPE_ALARM = (1 << 3); // 报警 + int HDISK_RECTYPE_VILOST = (1 << 4); // 视频丢失 + int HDISK_RECTYPE_VIHIDE = (1 << 5); // 视频遮挡 + int HDISK_RECTYPE_OTHER = (1 << 6); // 其他 + int HDISK_RECTYPE_BACKUP = (1 << 7); // 备份 + int HDISK_RECTYPE_NETANOMALY = (1 << 8); // 网络异常 + int HDISK_RECTYPE_PLATE = (1 << 9); // 车牌识别触发抓拍 + int HDISK_RECTYPE_TEMP = (1 << 10); // 全局测温和高温报警 + int HDISK_RECTYPE_SMART_ANALYSIS = (1 << 11); // 智能分析报警 + int HDISK_RECTYPE_MQTT_NARI = (1 << 12); // NARI通过MQTT下发snapShot指令 + int HDISK_RECTYPE_THRESHOLD = (1 << 13); // 阈值测温报警 + int HDISK_RECTYPE_TEMPDIFF = (1 << 14); // 温度对比报警 + int HDISK_RECTYPE_MASK = 0xff; // 录像掩码 + + // ───────────────────────────────────────────────────────────────────── + // 设备类型 — VSNETStructDef.h + // ───────────────────────────────────────────────────────────────────── + int DEVICE_DVS = 0x01; // 视频服务器 + int DEVICE_DVR = 0x02; // 硬盘录像机 + int DEVICE_IPC = 0x03; // 网络摄像机 + int DEVICE_NVR = 0x04; // 网络录像机 + + // ───────────────────────────────────────────────────────────────────── + // 用户权限 — VSNETStructDef.h + // ───────────────────────────────────────────────────────────────────── + int VSNET_USER_RIGHT_ADMIN = 1; // 管理员权限 + int VSNET_USER_RIGHT_HIOPER = 2; // 高级操作员 + int VSNET_USER_RIGHT_OPERIAL = 3; // 操作员 + + // ───────────────────────────────────────────────────────────────────── + // 最大数量限制 — VSNETStructDef.h + // ───────────────────────────────────────────────────────────────────── + int VSNET_DVR_MAXCH = 64; // 最大通道数 + int VSNET_DVR_MAXALARMOUT = 16; // 最大报警输出数 + int VSNET_DVR_MAXTRACKNUM = 16; // 最大轨道数 + int VSNET_DVR_MAXVONUM = 8; // 最大VO数 + int VSNET_DVR_MAXSTM = 4; // 最大码流数 + int VSNET_OSDTITLE_NUM = 6; // OSD标题最大数 + int VSNET_CAPTURE_OSDSTR_LENTH = 60; // 抓图OSD字符串最大长度 + int VSNET_NETCFG_IPV6LEN = 48; // IPv6配置长度 + int VSNET_DVR_GUI_PORT = 10000; // DVR GUI内部通信端口 + int TEMP_AREA_NUM = 1; // 测温区域数量 + int MAX_OSDSTRLEN = 200; // OSD字符串最大长度 + int REGIONTEMPNUM = 8; // 区域测温数量 + int ALARM_LEVEL_NUM = 5; // 报警等级数 + int MAX_SSIDNUM = 40; // WiFi SSID最大数量 + int MAX_FILE_DATA = 10; // 文件数据最大数 + int LOG_MAX_NUM = 2500; // 日志最大条数 + + // ───────────────────────────────────────────────────────────────────── + // 云台控制码 — VSNETStructDef.h (enum PTZCtrlCode) + // ───────────────────────────────────────────────────────────────────── + int PTZ_LEFT = 0; // 左 + int PTZ_RIGHT = 1; // 右 + int PTZ_UP = 2; // 上 + int PTZ_DOWN = 3; // 下 + int PTZ_IRISADD = 4; // 光圈+ + int PTZ_IRISDEC = 5; // 光圈- + int PTZ_FOCUSADD = 6; // 聚焦+ + int PTZ_FOCUSDEC = 7; // 聚焦- + int PTZ_ZOOMADD = 8; // 变倍+ + int PTZ_ZOOMDEC = 9; // 变倍- + int PTZ_GOTOPOINT = 10; // 转到预置点 + int PTZ_SETPOINT = 11; // 设置预置点 + int PTZ_AUTO = 12; // 自动 + int PTZ_STOP = 13; // 停止 + int PTZ_LEFTSTOP = 14; // 左停止 + int PTZ_RIGHTSTOP = 15; // 右停止 + int PTZ_UPSTOP = 16; // 上停止 + int PTZ_DOWNSTOP = 17; // 下停止 + int PTZ_IRISADDSTOP = 18; // 光圈+停止 + int PTZ_IRISDECSTOP = 19; // 光圈-停止 + int PTZ_FOCUSADDSTOP = 20; // 聚焦+停止 + int PTZ_FOCUSDECSTOP = 21; // 聚焦-停止 + int PTZ_ZOOMADDSTOP = 22; // 变倍+停止 + int PTZ_ZOOMDECSTOP = 23; // 变倍-停止 + int PTZ_LIGHT = 24; // 灯光 + int PTZ_LIGHTSTOP = 25; // 灯光停止 + int PTZ_RAIN = 26; // 雨刷 + int PTZ_RAINSTOP = 27; // 雨刷停止 + int PTZ_TRACK = 28; // 跟踪 + int PTZ_TRACKSTOP = 29; // 跟踪停止 + int PTZ_DEVOPEN = 30; // 设备打开 + int PTZ_DECCLOSE = 31; // 解码器关闭 + int PTZ_AUTOSTOP = 32; // 自动停止 + int PTZ_CLEARPOINT = 33; // 清除预置点 + int PTZ_LEFTUP = 200; // 左上 + int PTZ_LEFTUPSTOP = 201; // 左上停止 + int PTZ_RIGHTUP = 202; // 右上 + int PTZ_RIGHTUPSTOP = 203; // 右上停止 + int PTZ_LEFTDOWN = 204; // 左下 + int PTZ_LEFTDOWNSTOP = 205; // 左下停止 + int PTZ_RIGHTDOWN = 206; // 右下 + int PTZ_RIGHTDOWNSTOP = 207; // 右下停止 + int PTZ_LOOP_START = 208; // 开始预置点巡航; value 巡航线路; priority 巡航时间(0,5-1800) + int PTZ_LOOP_STOP = 209; // 停止预置点巡航; value 巡航线路 + + // ───────────────────────────────────────────────────────────────────── + // 硬盘状态 + // ───────────────────────────────────────────────────────────────────── + int HDISK_UNFORMATTED = 0; // 未格式化 + int HDISK_FORMATTING = 1; // 格式化中 + int HDISK_FORMATFINISH = 2; // 格式化完成 + + // ───────────────────────────────────────────────────────────────────── + // FTP连接状态 + // ───────────────────────────────────────────────────────────────────── + int VS_FTP_LINK_OFF = 0; // 连接关闭 + int VS_FTP_LINK_SUCCESS = 1; // 连接成功 + int VS_FTP_LINK_FAIL = 2; // 连接失败 + + // ───────────────────────────────────────────────────────────────────── + // 视频分辨率 — VSNETStructDef.h (enum ENUM_VSNET_VIDEO_RESOLUTION) + // ───────────────────────────────────────────────────────────────────── + int VSNET_VIDEO_RESOLUTION_QCIF = 0; // 176*144 + int VSNET_VIDEO_RESOLUTION_CIF = 1; // 352*288 + int VSNET_VIDEO_RESOLUTION_2CIF = 2; // 704*288 + int VSNET_VIDEO_RESOLUTION_4CIF = 3; // 704*576 (D1) + int VSNET_VIDEO_RESOLUTION_DCIF = 4; // 528*384 + int VSNET_VIDEO_RESOLUTION_QVGA = 5; // 320*240 + int VSNET_VIDEO_RESOLUTION_VGA_60HZ = 6; // 640*480 + int VSNET_VIDEO_RESOLUTION_SVGA_60HZ = 7; // 800*600 + int VSNET_VIDEO_RESOLUTION_XGA_60HZ = 8; // 1024*768 + int VSNET_VIDEO_RESOLUTION_SXGA_60HZ = 9; // 1280*1024 + int VSNET_VIDEO_RESOLUTION_UXGA_60HZ = 10; // 1600*1200 + int VSNET_VIDEO_RESOLUTION_720P = 11; // 1280*720 + int VSNET_VIDEO_RESOLUTION_HDTV = 12; // 1920*1080 + int VSNET_VIDEO_RESOLUTION_SVGA_75HZ = 13; // 800*600 + int VSNET_VIDEO_RESOLUTION_XGA_75HZ = 14; // 1024*768 + int VSNET_VIDEO_RESOLUTION_720P_50HZ = 15; // 1280*720 50Hz + int VSNET_VIDEO_RESOLUTION_720P_60HZ = 16; // 1280*720 60Hz + int VSNET_VIDEO_RESOLUTION_1080P_50HZ = 17; // 1920*1080 50Hz + int VSNET_VIDEO_RESOLUTION_1080P_60HZ = 18; // 1920*1080 60Hz + int VSNET_VIDEO_RESOLUTION_LTF = 19; // 240*192 + int VSNET_VIDEO_RESOLUTION_WQVGA1 = 20; // 480*352 + int VSNET_VIDEO_RESOLUTION_WQVGA2 = 21; // 480*272 + int VSNET_VIDEO_RESOLUTION_UVGA_50HZ = 22; // 1280*960 50Hz + int VSNET_VIDEO_RESOLUTION_UVGA_60HZ = 23; // 1280*960 60Hz + int VSNET_VIDEO_RESOLUTION_1080P_30HZ = 24; // 1920*1080 30Hz + int VSNET_VIDEO_RESOLUTION_1080I_50HZ = 25; // 1920*1080 50Hz + int VSNET_VIDEO_RESOLUTION_1080I_60HZ = 26; // 1920*1080 60Hz + int VSNET_VIDEO_RESOLUTION_SXGA_75HZ = 27; // 1280*1024 75Hz + int VSNET_VIDEO_RESOLUTION_WXGA_60HZ = 28; // 1280*800 60Hz + int VSNET_VIDEO_RESOLUTION_WXGA_75HZ = 29; // 1280*800 75Hz + int VSNET_VIDEO_RESOLUTION_SXGAP_60HZ = 30; // 1400*1050 60Hz (SXGA+) + int VSNET_VIDEO_RESOLUTION_SXGAP_75HZ = 31; // 1400*1050 75Hz (SXGA+) + int VSNET_VIDEO_RESOLUTION_WXGAP_60HZ = 32; // 1440*900 60Hz (WXGA+) + int VSNET_VIDEO_RESOLUTION_WSXGAP_60HZ = 33; // 1680*1050 60Hz (WSXGA+) + int VSNET_VIDEO_RESOLUTION_WSUVGAP_60HZ = 34; // 1920*1080 60Hz (WSUVGA+) + int VSNET_VIDEO_RESOLUTION_1366X768_60HZ = 35; // 1366*768 60Hz + int VSNET_VIDEO_RESOLUTION_WXGA_59HZ = 36; // 1280*800 59Hz + int VSNET_VIDEO_RESOLUTION_1280X720_59HZ = 37; // 1280*720 59Hz + int VSNET_VIDEO_RESOLUTION_1360X768_60HZ = 38; // 1360*768 60Hz + + // ───────────────────────────────────────────────────────────────────── + // 抓图错误码 + // ───────────────────────────────────────────────────────────────────── + int EN_CEC_SUCCESS = 0x10; // 成功 + int EN_CEC_PARAM_INVALID = 0x11; // 参数无效 + int EN_CEC_PATH_INVALID = 0x12; // 文件路径无效 + int EN_CEC_MEM_NOT_ENOUGH_RAW = 0x13; // 内存不够存储raw数据 + int EN_CEC_WRITE_RAW = 0x14; // 写入raw数据失败 + int EN_CEC_MEM_NOT_ENOUGH_VIS = 0x15; // 内存不够存可见光数据 + int EN_CEC_WRITE_VIS = 0x16; // 写入可见光数据失败 + int EN_CEC_MEM_NOT_ENOUGH_PRE = 0x17; // 内存不够存预览数据 + int EN_CEC_WRITE_PRE = 0x18; // 写入预览数据失败 + int EN_CEC_WRITE_SENSOR_INFO = 0x19; // 写入传感器信息失败 + int EN_CEC_WRITE_CALIB_INFO = 0x1a; // 写入校准信息失败 + int EN_CEC_WRITE_ENV_INFO = 0x1b; // 写入环境信息失败 + int EN_CEC_WRITE_PALETTE_INFO = 0x1C; // 写入调色板信息失败 + int EN_CEC_WRITE_STRENGTH_INFO = 0x1D; // 写入强度信息失败 + int EN_CEC_COLLECT_FILE_INFO = 0x1E; // 写入采集文件信息失败 + int EN_CEC_MEM_NOT_ENOUGH = 0x1F; // 内存不足 + int EN_CEC_DECODE_TEMPERATURE = 0x20; // 解析温度失败 + int EN_CEC_UNDEFINE = 0x21; // 未知错误 + + // ───────────────────────────────────────────────────────────────────── + // 文件类型 + // ───────────────────────────────────────────────────────────────────── + int EN_FT_SDK_LCR = 0; // LCR红外图 + int EN_FT_SDK_CHANNEL_JPG = 1; // 通道JPG + int EN_FT_SDK_CHANNEL_BMP = 2; // 通道BMP + + // ───────────────────────────────────────────────────────────────────── + // 调色板模式 + // ───────────────────────────────────────────────────────────────────── + int DEV_PALETE_WHITEHOT = 0; // 白热 + int DEV_PALETE_BLACKHOT = 1; // 黑热 + int DEV_PALETE_FUSION = 2; // 融合 + int DEV_PALETE_HOTMETAL = 2; // HOTMETAL + int DEV_PALETE_RAINBOW = 3; // 彩虹 + int DEV_PALETE_GLOBOW = 4; // GLOBOW + int DEV_PALETE_IRON = 5; // 铁红 + int DEV_PALETE_IRON2 = 6; // IRON2 + int DEV_PALETE_SEPIA = 7; // SEPIA + int DEV_PALETE_COLOR = 8; // COLOR + int DEV_PALETE_COLOR2 = 9; // COLOR2 + int DEV_PALETE_ICEFIRE = 10; // ICEFIRE + int DEV_PALETE_RAIN = 11; // RAIN + int DEV_PALETE_REDHOT = 12; // 红热 + int DEV_PALETE_GREENHOT = 13; // 绿热 + int DEV_PALETE_GREYRED = 14; // 灰红 + int DEV_PALETE_LAVA = 15; // 熔岩 + int DEV_PALETE_INSTALERT = 16; // InstAlert + int DEV_PALETE_ARCTIC = 17; // 北极 + + // ───────────────────────────────────────────────────────────────────── + // 录像文件格式 + // ───────────────────────────────────────────────────────────────────── + int RECDT_INVALID = 10; // 录像格式无效 + int RECDT_AUTO_BY_FILE_NAME = 11; // 根据文件名自动判断文件格式 + int RECDT_PRIVATE_MP4 = 12; // 私有mp4文件(只能用私有播放器播放) + int RECDT_MP4 = 13; // MP4 + int RECDT_MOV = 14; // MOV + int RECDT_ASF = 15; // ASF + int RECDT_AVI = 16; // AVI + + // ───────────────────────────────────────────────────────────────────── + // 融合视图模式 + // ───────────────────────────────────────────────────────────────────── + int EN_MODE_VIS = 1; // 可见光视图 + int EN_MODE_FUSION = 2; // 融合视图 + + // ───────────────────────────────────────────────────────────────────── + // 设备校准类型 + // ───────────────────────────────────────────────────────────────────── + int EN_DCT_TEMP = 0x40; // 校准温度 + int EN_DCT_K = 0x41; // K值 + int EN_DCT_SENSOR = 0x42; // Sensor + int EN_DCT_BLIND = 0x43; // 盲元 + int EN_DCT_TABLE_TEMP = 0x44; // 温度表 + int EN_DCT_B = 0x45; // B值 + int EN_DCT_COMPENSATE = 0x46; // 非均匀性补偿 + + // ───────────────────────────────────────────────────────────────────── + // 智能分析类型 + // ───────────────────────────────────────────────────────────────────── + int EN_IAT_INVALID = 0; // 无效 + int EN_IAT_CORDON = 1; // 警戒线 + int EN_IAT_REGION_ENTRY = 2; // 进入区域 + int EN_IAT_REGION_LEAVE = 3; // 离开区域 + int EN_IAT_GOODS_LEFT = 4; // 物品遗留 + int EN_IAT_GOODS_MOVE = 5; // 物品搬移 + int EN_IAT_TARFILTER_MIN = 6; // 过滤目标-最小尺寸 + int EN_IAT_TARFILTER_MAX = 7; // 过滤目标-最大尺寸 + int EN_IAT_REGIONSHIELD = 8; // 区域屏蔽 + + // ───────────────────────────────────────────────────────────────────── + // 人体校准状态 + // ───────────────────────────────────────────────────────────────────── + int HUMANCALI_COMPLETE = 0; // 完成 + int HUMANCALI_FFC_IMMINENT = 1; // FFC即将开始 + int HUMANCALI_WAIT_FOR_COLLECT_DATA = 2; // 等待采集数据 + int HUMANCALI_COLLECT_DATA_IN_PROGRESS = 3; // 采集数据中 + int HUMANCALI_CALC_IN_PROGRESS = 4; // 计算中 + + // ───────────────────────────────────────────────────────────────────── + // 人体校准错误码 + // ───────────────────────────────────────────────────────────────────── + int HUMANCALI_SUCCESS = 0; // 成功 + int HUMANCALI_FAIL = 1; // 失败 + int HUMANCALI_BUSY = 2; // 忙 + int HUMANCALI_TFPA_INSTABILITY = 3; // FPA不稳定 + int HUMANCALI_COLLECT_DATA_FAIL = 4; // 采集数据失败 + int HUMANCALI_CALC_FAIL = 5; // 计算失败 + int HUMANCALI_OBJTEMP_ERROR = 6; // 目标温度错误 + int HUMANCALI_RAW_INSTABILITY = 7; // Raw不稳定 + + // ───────────────────────────────────────────────────────────────────── + // 人头框尺寸类型 + // ───────────────────────────────────────────────────────────────────── + int HEADBOX_SIZE_BY_AREA = 0; // 按面积 + int HEADBOX_SIZE_BY_WIDTH = 1; // 按宽度 + int HEADBOX_SIZE_BY_HEIGHT = 2; // 按高度 + + /** + * MessageOpt 命令码 — IRNET_ClientMessageOpt 的 opt 参数。 + * 共 437 个命令,用于读写设备各项配置参数。 + */ + interface MessageOpt { + int MESSAGE_SERVERCHS = 1; // 查询通道(探头号)以及数据流数目 + int MESSAGE_CMD_RESET = 2; // 重启服务器 + int MESSAGE_CMD_GETGLOBALPARAM = 3; // 获取全局参数 + int MESSAGE_CMD_SETGLOBALPARAM = 4; // 设置全局参数 + int MESSAGE_GETCHANNELPARAM = 5; // 获取通道参数 + int MESSAGE_SETCHANNELPARAM = 6; // 设置通道参数 + int MESSAGE_CMD_PARAMDEFAULT = 7; // 恢复设备默认参数(普通) + int MESSAGE_CMD_GETSERIAL = 8; // 获取串口参数 + int MESSAGE_CMD_SETSERIAL = 9; // 设置串口参数 + int MESSAGE_CMD_GETSYSTIME = 10; // 获取系统时间 + int MESSAGE_CMD_SETSYSTIME = 11; // 设置系统时间 + int MESSAGE_CMD_GETSERIALNO = 12; // 获取设备序列号 + int MESSAGE_CMD_GETSYSUSER = 13; // 获取服务器端用户 + int MESSAGE_CMD_SETSYSUSER = 14; // 设置服务器端用户 + int MESSAGE_CMD_OUTPUTCTRL = 15; // 控制报警输出(用户操作) + int MESSAGE_CMD_OUTPUTSTATUS = 16; // 报警输出状态 + int MESSAGE_CMD_PTZCMDFILE = 17; // 加载云台控制协议配置文件 + int MESSAGE_CMD_PTZCMDNAME = 18; // 获取云台控制协议文件名 + int MESSAGE_CMD_SETSUBCHANNELPARAM = 19; // 设置服务器的子通道参数 + int MESSAGE_CMD_CAPTUREJPEG = 20; // 远程JPEG抓图(图像暂存于设备) + int MESSAGE_CMD_GETDISKSTATE = 21; // 获取硬盘状态 + int MESSAGE_CMD_FORMATDISK = 22; // 格式化硬盘 + int MESSAGE_CMD_ENCKEYFRAME = 23; // 使服务器产生一个I帧 + int MESSAGE_CMD_GETPPPOEPARAM = 24; // 获取PPPOE参数 + int MESSAGE_CMD_SETPPPOEPARAM = 25; // 设置PPPOE参数 + int MESSAGE_CMD_GETSERIAL232 = 26; // 获取RS232参数 + int MESSAGE_CMD_SETSERIAL232 = 27; // 设置RS232参数 + int MESSAGE_CMD_GETDHCP = 28; // 获取DHCP参数 + int MESSAGE_CMD_SETDHCP = 29; // 设置DHCP参数 + int MESSAGE_CMD_GETUPNPCFG = 30; // 获取UPNP配置参数 + int MESSAGE_CMD_SETUPNPCFG = 31; // 设置UPNP配置参数 + int MESSAGE_CMD_GETUPNPSTATUS = 32; // 获取UPNP状态 + int MESSAGE_CMD_GETMAILCFG = 33; // 获取邮件服务器信息 + int MESSAGE_CMD_SETMAILCFG = 34; // 设置邮件服务器信息 + int MESSAGE_CMD_GETTIMERCAP = 35; // 获取定时抓图参数 + int MESSAGE_CMD_SETTIMERCAP = 36; // 设置定时抓图参数 + int MESSAGE_CMD_GETSYSSUPPORTEX = 37; // 获取系统扩展支持信息 + int MESSAGE_CMD_GETDVRSENSORALARM = 38; // 获取DVR探头报警参数 + int MESSAGE_CMD_SETDVRSENSORALARM = 39; // 设置DVR探头报警参数 + int MESSAGE_CMD_GETENCODETYPE = 40; // 获取编码参数 + int MESSAGE_CMD_SETENCODETYPE = 41; // 设置编码参数 + int MESSAGE_CMD_MAILTEST = 42; // 邮件测试 + int MESSAGE_CMD_GETRTSPPARAMEX = 43; // 获取RTSP参数 + int MESSAGE_CMD_SETRTSPPARAMEX = 44; // 设置RTSP参数 + int MESSAGE_CMD_GETTIMEZONE = 45; // 获取服务器时区参数 + int MESSAGE_CMD_SETTIMEZONE = 46; // 设置服务器时区参数 + int MESSAGE_CMD_GETCHANNELOSD_EX = 47; // 获取OSD参数(扩展) + int MESSAGE_CMD_SETCHANNELOSD_EX = 48; // 设置OSD参数(扩展) + int MESSAGE_CMD_GETFLASHINFO = 49; // 获取Flash版本信息 + int MESSAGE_CMD_GETUPNPPORTINFO = 50; // 获取UPNP端口信息 + int MESSAGE_CMD_SET_FFCCTRL = 51; // 快门控制 + int MESSAGE_CMD_GET_CAPTURETYPE = 52; // 获取抓图类型 + int MESSAGE_CMD_SET_CAPTURETYPE = 53; // 设置抓图类型 + int MESSSGE_CMD_GET_OSDPARAM = 54; // 获取OSD参数 + int MESSSGE_CMD_SET_OSDPARAM = 55; // 设置OSD参数 + int MESSSGE_CMD_GET_IROSDPARAM = 56; // 获取红外OSD参数 + int MESSSGE_CMD_SET_IROSDPARAM = 57; // 设置红外OSD参数 + int MESSSGE_CMD_GET_REGIONTEMPPARAM = 58; // 获取区域测温参数(普通) + int MESSSGE_CMD_SET_REGIONTEMPPARAM = 59; // 设置区域测温参数(普通) + int MESSSGE_CMD_GET_REGIONTEMPALARM = 60; // 获取区域测温报警参数 + int MESSSGE_CMD_SET_REGIONTEMPALARM = 61; // 设置区域测温报警参数 + int MESSSGE_CMD_GET_REGIONTEMPVALUE = 62; // 获取区域测温温度值 + int MESSSGE_CMD_GET_VIDEOOUTMODE = 63; // 获取视频输出模式 + int MESSSGE_CMD_SET_VIDEOOUTMODE = 64; // 设置视频输出模式 + int MESSSGE_CMD_GET_TEMPDATA = 65; // 获取温度数据 + int MESSSGE_CMD_GET_GLOBALTEMPALARM = 66; // 获取全局测温报警参数 + int MESSSGE_CMD_SET_GLOBALTEMPALARM = 67; // 设置全局测温报警参数 + int MESSAGE_CMD_GET_IR_VIPARAM = 68; // 获取红外图像视频输入参数 + int MESSAGE_CMD_SET_IR_VIPARAM = 69; // 设置红外图像视频输入参数 + int MESSAGE_CMD_GET_IR_DDEPARAM = 70; // 获取红外图像DDE参数 + int MESSAGE_CMD_SET_IR_DDEPARAM = 71; // 设置红外图像DDE参数 + int MESSAGE_CMD_GET_IR_STRETCHMODE = 72; // 获取红外图像拉伸模式 + int MESSAGE_CMD_SET_IR_STRETCHMODE = 73; // 设置红外图像拉伸模式 + int MESSAGE_CMD_GET_TAUGAINMODE = 74; // 获取TAU增益模式 + int MESSAGE_CMD_SET_TAUGAINMODE = 75; // 设置TAU增益模式 + int MESSAGE_CMD_GET_GPSINFO = 76; // 获取GPS信息 + int MESSAGE_CMD_SET_GPSINFO = 77; // 设置GPS信息 + int MESSAGE_CMD_GETDVRSYSUSEREX = 78; // 获取设备用户信息 + int MESSAGE_CMD_SETDVRSYSUSEREX = 79; // 设置设备用户信息 + int MESSAGE_CMD_REC_REMOTE_BEG = 80; // 远程录像开始 + int MESSAGE_CMD_REC_REMOTE_END = 81; // 远程录像结束 + int MESSAGE_CMD_GET_MSDSTATUS = 82; // SD卡空间获取 + int MESSAGE_CMD_GET_CAL_TEMP_IN_AREA = 83; // 获取框内温度 + int MESSAGE_CMD_SET_CAL_TEMP_IN_AREA = 84; // 设置框内温度 + int MESSAGE_CMD_GET_PWMUART_CFG = 85; // 获取电机参数 + int MESSAGE_CMD_SET_PWMUART_CFG = 86; // 设置电机参数 + int MESSAGE_CMD_GET_TEMP_ALARM_PARAM = 87; // 温度超限报警 + int MESSAGE_CMD_SET_TEMP_ALARM_PARAM = 88; // 温度超限报警 + int MESSAGE_CMD_GET_RADMET_PARAM = 89; // 辐射参数获取 + int MESSAGE_CMD_SET_RADMET_PARAM = 90; // 辐射参数设置 + int MESSAGE_CMD_GET_STILLCAPTURE = 91; // 定时抓图控制 + int MESSAGE_CMD_SET_STILLCAPTURE = 92; // 定时抓图控制 + int MESSAGE_CMD_GET_ALARM_INPUT_STATUS = 93; // 获取报警输入探头状态 + int MESSAGE_CMD_GET_TEMPALARMCTRL = 94; // 测温报警控制 + int MESSAGE_CMD_SET_TEMPALARMCTRL = 95; // 测温报警控制 + int MESSAGE_CMD_GET_SDCARDFULLCTRL = 96; // SD卡满控制 + int MESSAGE_CMD_SET_SDCARDFULLCTRL = 97; // SD卡满控制 + int MESSAGE_CMD_GET_FIREPOINTPARAM = 98; // 获取火点参数 + int MESSAGE_CMD_SET_FIREPOINTPARAM = 99; // 设置火点参数 + int MESSAGE_CMD_GET_FIREPOINT = 100; // 获取火点 + int MESSAGE_CMD_GET_FIREBEHAVIOURPARAM = 101; // 获取火警参数 + int MESSAGE_CMD_SET_FIREBEHAVIOURPARAM = 102; // 设置火警参数 + int MESSAGE_CMD_GET_FIREBEHAVIOUR = 103; // 获取火警 + int MESSAGE_CMD_GET_OSD_REGION_TRANSPARENT_PARAM = 104; // OSD区域透明度参数 + int MESSAGE_CMD_SET_OSD_REGION_TRANSPARENT_PARAM = 105; // OSD区域透明度参数 + int MESSAGE_CMD_GET_BUZZER_ENABLE = 106; // 蜂鸣器使能 + int MESSAGE_CMD_SET_BUZZER_ENABLE = 107; // 蜂鸣器使能 + int MESSAGE_CMD_GETREMOTEHOST = 108; // 远程主机 + int MESSAGE_CMD_SETREMOTEHOST = 109; // 远程主机 + int MESSAGE_CMD_GET_REGIONTEMPALARMCTRL = 110; // 区域温度报警控制 + int MESSAGE_CMD_SET_REGIONTEMPALARMCTRL = 111; // 区域温度报警控制 + int MESSAGE_CMD_GET_TEMPMEASURETYPE = 112; // 测温类型的区域测温参数 + int MESSAGE_CMD_SET_TEMPMEASURETYPE = 113; // 测温类型的区域测温参数 + int MESSAGE_CMD_GET_AREATEMPCOMPARECTRL = 114; // 区域温度对比控制 + int MESSAGE_CMD_SET_AREATEMPCOMPARECTRL = 115; // 区域温度对比控制 + int MESSAGE_CMD_GET_REGIONOSDNAME = 116; // 区域名称OSD + int MESSAGE_CMD_SET_REGIONOSDNAME = 117; // 区域名称OSD + int MESSAGE_GETALARMPARAM = 118; // 报警参数 + int MESSAGE_SETALARMPARAM = 119; // 报警参数 + int MESSAGE_CMD_GETMOTIONPARAM = 120; // 移动侦测参数 + int MESSAGE_CMD_SETMOTIONPARAM = 121; // 移动侦测参数 + int MESSAGE_CMD_GETVIDEOMASK = 122; // 视频遮挡参数 + int MESSAGE_CMD_SETVIDEOMASK = 123; // 视频遮挡参数 + int MESSAGE_CMD_GETCHANNELOSD = 124; // 视频叠加参数 + int MESSAGE_CMD_SETCHANNELOSD = 125; // 视频叠加参数 + int MESSAGE_CMD_AFFIRMUSER = 126; // 验证用户 + int MESSAGE_CMD_GETTIMEDRESET = 127; // 定时重启 + int MESSAGE_CMD_SETTIMEDRESET = 128; // 定时重启 + int MESSAGE_CMD_GETHIDEALARM = 129; // 遮挡报警 + int MESSAGE_CMD_SETHIDEALARM = 130; // 遮挡报警 + int MESSAGE_CMD_GETSUBCHANNELPARAM = 131; // 子通道参数 + int MESSAGE_CMD_GETRECORDPARAM = 132; // 硬盘录像参数 + int MESSAGE_CMD_SETRECORDPARAM = 133; // 硬盘录像参数 + int MESSAGE_CMD_GETJPEGCAPPARAM = 134; // JPEG抓图参数 + int MESSAGE_CMD_SETJPEGCAPPARAM = 135; // JPEG抓图参数 + int MESSAGE_CMD_GETSENSORALARM = 136; // 探头报警 + int MESSAGE_CMD_SETSENSORALARM = 137; // 探头报警 + int MESSAGE_CMD_GETAUDIOPARAM = 138; // 音频参数 + int MESSAGE_CMD_SETAUDIOPARAM = 139; // 音频参数 + int MESSAGE_CMD_GETCDMAPARAM = 140; // CDMA参数 + int MESSAGE_CMD_SETCDMAPARAM = 141; // CDMA参数 + int MESSAGE_CMD_GETWIFIPARAM = 142; // WiFi参数 + int MESSAGE_CMD_SETWIFIPARAM = 143; // WiFi参数 + int MESSAGE_CMD_GETLINKCONFIG = 144; // 连接配置参数 + int MESSAGE_CMD_SETLINKCONFIG = 145; // 连接配置参数 + int MESSAGE_CMD_GETDDNSEXPARAM = 146; // DDNS连接参数 + int MESSAGE_CMD_SETDDNSEXPARAM = 147; // DDNS连接参数 + int MESSAGE_CMD_GETEXALARMPARAM = 148; // 外部报警参数 + int MESSAGE_CMD_SETEXALARMPARAM = 149; // 外部报警参数 + int MESSAGE_CMD_GETHUMITUREPRAM = 150; // 温湿度报警参数 + int MESSAGE_CMD_SETHUMITUREPRAM = 151; // 温湿度报警参数 + int MESSAGE_CMD_GETVIDEOOFFSET = 152; // 视频偏移量 + int MESSAGE_CMD_SETVIDEOOFFSET = 153; // 视频偏移量 + int MESSAGE_CMD_GETVIDEOMASKAREA = 154; // 视频遮挡区域 + int MESSAGE_CMD_SETVIDEOMASKAREA = 155; // 视频遮挡区域 + int MESSAGE_CMD_GETSNMPCONFIG = 156; // SNMP配置参数 + int MESSAGE_CMD_SETSNMPCONFIG = 157; // SNMP配置参数 + int MESSAGE_CMD_GETALARMSMS = 158; // 报警短信参数 + int MESSAGE_CMD_SETALARMSMS = 159; // 报警短信参数 + int MESSAGE_CMD_GETALARMTYPE = 160; // 探头类型 + int MESSAGE_CMD_SETALARMTYPE = 161; // 探头类型 + int MESSAGE_CMD_GETFTP = 162; // FTP信息 + int MESSAGE_CMD_SETFTP = 163; // FTP信息 + int MESSAGE_CMD_GETCCDPARAM = 164; // CCD参数 + int MESSAGE_CMD_SETCCDPARAM = 165; // CCD参数 + int MESSAGE_CMD_GETPLATFORMINFO = 166; // 平台信息 + int MESSAGE_CMD_SETPLATFORMINFO = 167; // 平台信息 + int MESSAGE_CMD_GETVI2VO = 168; // 图像环出使能 + int MESSAGE_CMD_SETVI2VO = 169; // 图像环出使能 + int MESSAGE_CMD_GETALARMFTPUPLOAD = 170; // 探头报警图片上传FTP参数 + int MESSAGE_CMD_SETALARMFTPUPLOAD = 171; // 探头报警图片上传FTP参数 + int MESSAGE_CMD_GETMOTIONCONTACTEX = 172; // 移动侦测报警联动扩展参数 + int MESSAGE_CMD_SETMOTIONCONTACTEX = 173; // 移动侦测报警联动扩展参数 + int MESSAGE_CMD_GETDVRMOTIONALARM = 174; // DVR移动侦测报警参数 + int MESSAGE_CMD_SETDVRMOTIONALARM = 175; // DVR移动侦测报警参数 + int MESSAGE_CMD_GETDVRHIDEALARM = 176; // DVR视频遮挡报警参数 + int MESSAGE_CMD_SETDVRHIDEALARM = 177; // DVR视频遮挡报警参数 + int MESSAGE_CMD_GETDVROTHERALARM = 178; // DVR其他报警参数 + int MESSAGE_CMD_SETDVROTHERALARM = 179; // DVR其他报警参数 + int MESSAGE_CMD_SETBKDISK = 180; // DVR备份硬盘 + int MESSAGE_CMD_GETSMARTINFO = 181; // DVR硬盘SMART信息 + int MESSAGE_CMD_GETVIEWPARAM = 182; // V0参数 + int MESSAGE_CMD_SETVIEWPARAM = 183; // V0参数 + int MESSAGE_CMD_GETLOOPVIEW = 184; // 轮巡控制参数 + int MESSAGE_CMD_SETLOOPVIEW = 185; // 轮巡控制参数 + int MESSAGE_CMD_GETDVRUSER = 186; // DVR用户信息 + int MESSAGE_CMD_SETDVRUSER = 187; // DVR用户信息 + int MESSAGE_CMD_GETDVRCHANNELOSD = 188; // DVR视频叠加参数 + int MESSAGE_CMD_SETDVRCHANNELOSD = 189; // DVR视频叠加参数 + int MESSAGE_CMD_GETVIDEOOFFSETEX = 190; // 视频偏移量(扩展) + int MESSAGE_CMD_SETVIDEOOFFSETEX = 191; // 视频偏移量(扩展) + int MESSAGE_CMD_GETDEVICEID = 192; // 设备ID + int MESSAGE_CMD_SETDEVICEID = 193; // 设备ID + int MESSAGE_CMD_GETKEYBOARDEX = 194; // 键盘参数 + int MESSAGE_CMD_SETKEYBOARDEX = 195; // 键盘参数 + int MESSAGE_CMD_GETCHOOSEPTZ = 196; // 选择云台 + int MESSAGE_CMD_SETCHOOSEPTZ = 197; // 选择云台 + int MESSAGE_CMD_GETDVRDOUBLEBITS = 198; // 双码流参数 + int MESSAGE_CMD_SETDVRDOUBLEBITS = 199; // 双码流参数 + int MESSAGE_CMD_GETPROTOCOLPARAM = 200; // 选择协议 + int MESSAGE_CMD_SETPROTOCOLPARAM = 201; // 选择协议 + int MESSAGE_CMD_GETFTPTIMEREC = 202; // FTP定时录像 + int MESSAGE_CMD_SETFTPTIMEREC = 203; // FTP定时录像 + int MESSAGE_CMD_GETSUBENCODETYPE = 204; // 子编码参数 + int MESSAGE_CMD_SETSUBENCODETYPE = 205; // 子编码参数 + int MESSAGE_CMD_GETPROLOOP = 206; // 预置点巡航 + int MESSAGE_CMD_SETPROLOOP = 207; // 预置点巡航 + int MESSAGE_CMD_GETAUDIOSILENT = 208; // 音频静音参数 + int MESSAGE_CMD_SETAUDIOSILENT = 209; // 音频静音参数 + int MESSAGE_CMD_GETDVRUSERSTATE = 210; // 用户状态 + int MESSAGE_CMD_SETDVRUSERSTATE = 211; // 用户状态 + int MESSAGE_CMD_GETREDUNDANCERECORD = 212; // 冗余录像状态 + int MESSAGE_CMD_SETREDUNDANCERECORD = 213; // 冗余录像状态 + int MESSAGE_CMD_GETTHIRDENCODEPARA = 214; // 第三码流参数 + int MESSAGE_CMD_SETTHIRDENCODEPARA = 215; // 第三码流参数 + int MESSAGE_CMD_GETTHIRDENCODETYPE = 216; // 第三编码格式 + int MESSAGE_CMD_SETTHIRDENCODETYPE = 217; // 第三编码格式 + int MESSAGE_CMD_GETPTZCTRLTIME = 218; // 云台连续控制时长 + int MESSAGE_CMD_SETPTZCTRLTIME = 219; // 云台连续控制时长 + int MESSAGE_CMD_GETAUDIOPARAMTYPE = 220; // 音频类型 + int MESSAGE_CMD_SETAUDIOPARAMTYPE = 221; // 音频类型 + int MESSAGE_CMD_GETDVRVOPARAM = 222; // DVR的视频输出参数 + int MESSAGE_CMD_SETDVRVOPARAM = 223; // DVR的视频输出参数 + int MESSAGE_CMD_GETVLCPARAM = 224; // VLC参数 + int MESSAGE_CMD_SETVLCPARAM = 225; // VLC参数 + int MESSAGE_CMD_GETNTPPARAM = 226; // NTP参数 + int MESSAGE_CMD_SETNTPPARAM = 227; // NTP参数 + int MESSAGE_CMD_GETBKDISK = 228; // 备份至硬盘 + int MESSAGE_CMD_GETVIDEOINTERESTAREA = 229; // 视频感兴趣区域参数 + int MESSAGE_CMD_SETVIDEOINTERESTAREA = 230; // 视频感兴趣区域参数 + int MESSAGE_CMD_GETVCAABILITY = 231; // 支持的智能分析能力 + int MESSAGE_CMD_GETCCDPARAMEX = 232; // Sensor参数 + int MESSAGE_CMD_SETCCDPARAMEX = 233; // Sensor参数 + int MESSAGE_CMD_GETSTORAGE = 234; // 硬盘信息(新) + int MESSAGE_CMD_SETSTORAGE = 235; // 硬盘信息(新) + int MESSAGE_CMD_GETSMART = 236; // 硬盘SMART信息(新) + int MESSAGE_CMD_GETEXACTTIMEZONE = 237; // 准确的时区 + int MESSAGE_CMD_SETEXACTTIMEZONE = 238; // 准确的时区 + int MESSAGE_CMD_GETTRAFFICLIGHTCFG = 239; // 红绿灯配置 + int MESSAGE_CMD_SETTRAFFICLIGHTCFG = 240; // 红绿灯配置 + int MESSAGE_CMD_GETRECORDSTREAMTYPE = 241; // 录像与码流类型 + int MESSAGE_CMD_SETRECORDSTREAMTYPE = 242; // 录像与码流类型 + int MESSAGE_CMD_GETWIFIMODE = 243; // WiFi模式 + int MESSAGE_CMD_SETWIFIMODE = 244; // WiFi模式 + int MESSAGE_CMD_GETALARMSHORTMSGPARAM = 245; // 报警短信参数 + int MESSAGE_CMD_SETALARMSHORTMSGPARAM = 246; // 报警短信参数 + int MESSAGE_CMD_GETNETERRORPARAM = 247; // 网络异常报警参数 + int MESSAGE_CMD_SETNETERRORPARAM = 248; // 网络异常报警参数 + int MESSAGE_CMD_GETDISKSELECTPARAM = 249; // 设备存储介质 + int MESSAGE_CMD_SETDISKSELECTPARAM = 250; // 设备存储介质 + int MESSAGE_CMD_GETDAYNIGHTPARAM = 251; // 日夜转换参数 + int MESSAGE_CMD_SETDAYNIGHTPARAM = 252; // 日夜转换参数 + int MESSAGE_CMD_GETVIDEOINTYPE = 253; // 视频输入类型 + int MESSAGE_CMD_SETVIDEOINTYPE = 254; // 视频输入类型 + int MESSAGE_CMD_GETWIFIENABLE = 255; // WiFi/3G支持信息 + int MESSAGE_CMD_GETNOISEMODEPARAM = 256; // 降噪参数 + int MESSAGE_CMD_SETNOISEMODEPARAM = 257; // 降噪参数 + int MESSAGE_CMD_GETVPNINFO = 258; // VPN参数 + int MESSAGE_CMD_SETVPNINFO = 259; // VPN参数 + int MESSAGE_CMD_GETWIFIINFO = 260; // WiFi信息 + int MESSAGE_CMD_GETPHOTO_SENSITIVE_TYPE = 261; // 光敏控制类型 + int MESSAGE_CMD_SETPHOTO_SENSITIVE_TYPE = 262; // 光敏控制类型 + int MESSAGE_CMD_GET_ENC_VPP_MAIN = 263; // 主码流视频预处理参数 + int MESSAGE_CMD_SET_ENC_VPP_MAIN = 264; // 主码流视频预处理参数 + int MESSAGE_CMD_SET_ENC_VPP_SUB = 265; // 子码流视频预处理参数 + int MESSAGE_CMD_GET_ENC_VPP_SUB = 266; // 子码流视频预处理参数 + int MESSAGE_CMD_SET_ENC_VPP_THIRD = 267; // 第三码流视频预处理参数 + int MESSAGE_CMD_GET_ENC_VPP_THIRD = 268; // 第三码流视频预处理参数 + int MESSAGE_CMD_SET_ENC_PROFILE_MAIN = 269; // 编码级别(主) + int MESSAGE_CMD_GET_ENC_PROFILE_MAIN = 270; // 编码级别(主) + int MESSAGE_CMD_SET_ENC_PROFILE_SUB = 271; // 编码级别(子) + int MESSAGE_CMD_GET_ENC_PROFILE_SUB = 272; // 编码级别(子) + int MESSAGE_CMD_SET_ENC_PROFILE_THIRD = 273; // 编码级别(第三) + int MESSAGE_CMD_GET_ENC_PROFILE_THIRD = 274; // 编码级别(第三) + int MESSAGE_CMD_GET_CCD_RGB_DEFAULT = 275; // Sensor的RGB参数 + int MESSAGE_CMD_SET_CCD_AI_CHECK = 276; // AI校验值 + int MESSAGE_CMD_GET_REMOTESTREAMTYPE = 277; // 远程回放上传码流类型 + int MESSAGE_CMD_SET_REMOTESTREAMTYPE = 278; // 远程回放上传码流类型 + int MESSAGE_CMD_GET_ENCRYPTIONTYPE = 279; // 加密方式 + int MESSAGE_CMD_SET_ENCRYPTIONTYPE = 280; // 加密方式 + int MESSAGE_CMD_GETSENSORPARAM_DEVTYPE = 281; // 远程参数中的设备类型 + int MESSAGE_CMD_SETSENSORPARAM_DEVTYPE = 282; // 远程参数中的设备类型 + int MESSAGE_CMD_GETDEVICECFG = 283; // NVR的模数转换配置 + int MESSAGE_CMD_SETDEVICECFG = 284; // NVR的模数转换配置 + int MESSAGE_CMD_GETCHANNELRECORDPLANEX = 285; // 通道录像计划 + int MESSAGE_CMD_SETCHANNELRECORDPLANEX = 286; // 通道录像计划 + int MESSAGE_CMD_GETMOTIONALARMAREA = 287; // 移动侦测区域 + int MESSAGE_CMD_SETMOTIONALARMAREA = 288; // 移动侦测区域 + int MESSAGE_CMD_GET_OSDBORDER = 289; // OSD边框参数 + int MESSAGE_CMD_SET_OSDBORDER = 290; // OSD边框参数 + int MESSAGE_CMD_GET_RESOLUTION = 291; // 支持的分辨率 + int MESSAGE_CMD_GET_QOS_TOS = 292; // 视频QOS优先级 + int MESSAGE_CMD_SET_QOS_TOS = 293; // 视频QOS优先级 + int MESSAGE_CMD_GET_SNMP_CFG = 294; // SNMP配置 + int MESSAGE_CMD_SET_SNMP_CFG = 295; // SNMP配置 + int MESSAGE_CMD_GET_IPV6_CFG = 296; // IPv6配置 + int MESSAGE_CMD_SET_IPV6_CFG = 297; // IPv6配置 + int MESSAGE_CMD_GET_SENSORVERSION = 298; // 获取Sensor版本号 + int MESSAGE_CMD_GET_WINCALIPARAM = 299; // 窗口校准参数 + int MESSAGE_CMD_SET_WINCALIPARAM = 300; // 窗口校准参数 + int MESSAGE_CMD_GET_SMT_ANALY_ADVANCE = 301; // 智能分析-高级参数 + int MESSAGE_CMD_SET_SMT_ANALY_ADVANCE = 302; // 智能分析-高级参数 + int MESSAGE_CMD_GET_DAYNIGHTPARAM_EX = 303; // 日夜参数 + int MESSAGE_CMD_SET_DAYNIGHTPARAM_EX = 304; // 日夜参数 + int MESSAGE_CMD_GET_IROSD2VISPARAM = 305; // 可见光添加红外OSD参数 + int MESSAGE_CMD_SET_IROSD2VISPARAM = 306; // 可见光添加红外OSD参数 + int MESSAGE_CMD_GET_CHANNELTYPE = 307; // 通道类型 + int MESSAGE_CMD_GET_ANTIFLICKER = 308; // 抗闪烁 + int MESSAGE_CMD_SET_ANTIFLICKER = 309; // 抗闪烁 + int MESSAGE_CMD_GET_TEMPREGIONOFFSET = 310; // 测温区域位置偏移 + int MESSAGE_CMD_SET_TEMPREGIONOFFSET = 311; // 测温区域位置偏移 + int MESSAGE_CMD_GET_TEMPVALUE_EX = 312; // 获取温度值(扩展) + int MESSAGE_CMD_GET_SENSOR_SERIALNO = 313; // 获取Sensor序列号 + int MESSAGE_CMD_SET_SENSOR_SERIALNO = 314; // 设置Sensor序列号 + int MESSAGE_CMD_GET_SWITCHMODE = 315; // 切换校准模式 + int MESSAGE_CMD_SET_SWITCHMODE = 316; // 切换校准模式 + int MESSAGE_CMD_TAU_FACDEFAULT = 317; // TAU恢复出厂默认 + int MESSAGE_CMD_TAU_SAVEPARAM = 318; // TAU保存参数 + int MESSAGE_CMD_GET_TAU_SEGMENT = 319; // TAU段表 + int MESSAGE_CMD_SET_TAU_SEGMENT = 320; // TAU段表 + int MESSAGE_CMD_GET_HT_BLACK_CLIPPING = 321; // 黑边裁切 + int MESSAGE_CMD_SET_HT_BLACK_CLIPPING = 322; // 黑边裁切 + int MESSAGE_CMD_GET_DENOISEPARAM = 323; // 降噪 + int MESSAGE_CMD_SET_DENOISEPARAM = 324; // 降噪 + int MESSAGE_CMD_GET_ROLLPARAM = 325; // 翻转 + int MESSAGE_CMD_SET_ROLLPARAM = 326; // 翻转 + int MESSAGE_CMD_GET_DIGITALOUTMODE = 327; // 数字输出模式 + int MESSAGE_CMD_SET_DIGITALOUTMODE = 328; // 数字输出模式 + int MESSAGE_CMD_GET_FFCMODE = 329; // FFC模式 + int MESSAGE_CMD_SET_FFCMODE = 330; // FFC模式 + int MESSAGE_CMD_GET_FFCFRAMEPARAM = 331; // 自动FFC帧数参数 + int MESSAGE_CMD_SET_FFCFRAMEPARAM = 332; // 自动FFC帧数参数 + int MESSAGE_CMD_GET_FFCTEMPPARAM = 333; // 自动FFC温度参数 + int MESSAGE_CMD_SET_FFCTEMPPARAM = 334; // 自动FFC温度参数 + int MESSAGE_CMD_GET_VTEMPTEMP = 335; // VTEMP温度参数 + int MESSAGE_CMD_SET_VTEMPTEMP = 336; // VTEMP温度参数 + int MESSAGE_CMD_GET_VTEMPREGION = 337; // VTEMP区域参数 + int MESSAGE_CMD_SET_VTEMPREGION = 338; // VTEMP区域参数 + int MESSAGE_CMD_GET_KENABLE = 339; // K值有效 + int MESSAGE_CMD_SET_KENABLE = 340; // K值有效 + int MESSAGE_CMD_GET_BENABLE = 341; // B值有效 + int MESSAGE_CMD_SET_BENABLE = 342; // B值有效 + int MESSAGE_CMD_GET_BLINDENABLE = 343; // 盲元有效 + int MESSAGE_CMD_SET_BLINDENABLE = 344; // 盲元有效 + int MESSAGE_CMD_GET_FILTEENABLE = 345; // 时域滤波有效 + int MESSAGE_CMD_SET_FILTEENABLE = 346; // 时域滤波有效 + int MESSAGE_CMD_GET_FILTEPARAM = 347; // 时域滤波系数 + int MESSAGE_CMD_SET_FILTEPARAM = 348; // 时域滤波系数 + int MESSAGE_CMD_GET_TRAN = 349; // 透传 + int MESSAGE_CMD_SET_TRAN = 350; // 透传 + int MESSAGE_CMD_GET_SMART_DATA = 351; // SmartData参数 + int MESSAGE_CMD_SET_SMART_DATA = 352; // SmartData参数 + int MESSAGE_CMD_GET_SENSOR_TEMP = 353; // 机芯各位置温度 + int MESSAGE_CMD_SET_WRITE_FLASH = 354; // 烧写Flash + int MESSAGE_CMD_GET_SENSOR_STATE = 355; // 当前Sensor状态 + int MESSAGE_CMD_GET_OBJTEMP_FLUXRANGE = 356; // 温度辐射范围 + int MESSAGE_CMD_GET_TAUNUCTABLEINDEXES = 357; // 获取当前支持的NUC Table段索引 + int MESSAGE_CMD_GET_TAUNUCTABLEFUNCTION = 358; // 获取当前TAU的支持的NUC Table检测功能 + int MESSAGE_CMD_SET_TAUNUCTABLEFUNCTION = 359; // 设置当前TAU的支持的NUC Table检测功能 + int MESSAGE_CMD_WNDCALIB_STARTUP = 360; // 窗口校准 启动 + int MESSAGE_CMD_WNDCALIB_CAPBASEDATA = 361; // 抓取N帧基准的基帧数据 + int MESSAGE_CMD_WNDCALIB_CAPOBJDATA = 362; // 抓取N帧目标的目标数据 + int MESSAGE_CMD_WNDCALIB_CALC = 363; // 计算窗口校准系数 + int MESSAGE_CMD_GET_WEBROMVER = 364; // 获取网页ROM版本 + int MESSAGE_CMD_FILLLIGHT_ON = 365; // 补光灯开 + int MESSAGE_CMD_FILLLIGHT_OFF = 366; // 补光灯关 + int MESSAGE_CMD_GET_ONVIFPARAM = 367; // Onvif参数 + int MESSAGE_CMD_SET_ONVIFPARAM = 368; // Onvif参数 + int MESSAGE_CMD_GET_IMAGEFUSEPARAM_EX = 369; // 图像融合参数 + int MESSAGE_CMD_SET_IMAGEFUSEPARAM_EX = 370; // 图像融合参数 + int MESSAGE_CMD_GET_FUSEOFFSET = 371; // 融合偏移 + int MESSAGE_CMD_SET_FUSEOFFSET = 372; // 融合偏移 + int MESSAGE_CMD_GET_IMAGEFLIPPARAM = 373; // 图像翻转参数 + int MESSAGE_CMD_SET_IMAGEFLIPPARAM = 374; // 图像翻转参数 + int MESSAGE_CMD_GET_PIXLETEMPERATURE = 375; // 获取像素点温度 + int MESSAGE_CMD_SET_PIXLETEMPERATURE = 376; // 设置像素点位置 + int MESSAGE_CMD_GET_POLYGONTEMPPARAM = 377; // 获取多边形测温区域参数 + int MESSAGE_CMD_SET_POLYGONTEMPPARAM = 378; // 设置多边形测温区域参数 + int MESSAGE_CMD_GET_HUMANCALIPARAM = 379; // 获取人体校准参数 + int MESSAGE_CMD_SET_HUMANCALIPARAM = 380; // 设置人体校准参数 + int MESSAGE_CMD_GET_TEMPSHIELDPARAM = 381; // 测温屏蔽区域 + int MESSAGE_CMD_SET_TEMPSHIELDPARAM = 382; // 测温屏蔽区域 + int MESSAGE_CMD_HUMANCALI_MANUAL = 383; // 人体校准(手动) + int MESSAGE_CMD_HUMANCALI_RESTORE = 384; // 人体校准(恢复) + int MESSAGE_CMD_GET_HUMANCALI_VISMATCHIR = 385; // 红外和可见光图像对应参数 + int MESSAGE_CMD_SET_HUMANCALI_VISMATCHIR = 386; // 红外和可见光图像对应参数 + int MESSAGE_CMD_GET_HUMANCALI_TEMPTABLE = 387; // 人体校准温度表 + int MESSAGE_CMD_SET_HUMANCALI_TEMPTABLE = 388; // 人体校准温度表 + int MESSAGE_CMD_GET_TEMPUNIT = 389; // 温度单位 + int MESSAGE_CMD_SET_TEMPUNIT = 390; // 温度单位 + int MESSAGE_CMD_GET_TEMPINFOLIST = 391; // 获取全局和各区域温度值信息 + int MESSAGE_CMD_GET_TEMPALARMCTRLEX = 392; // 测温报警控制(支持4个等级) + int MESSAGE_CMD_SET_TEMPALARMCTRLEX = 393; // 测温报警控制(支持4个等级) + int MESSAGE_CMD_GET_REGIONTEMPALARMCTRLEX = 394; // 区域温度报警控制(支持4个等级) + int MESSAGE_CMD_SET_REGIONTEMPALARMCTRLEX = 395; // 区域温度报警控制(支持4个等级) + int MESSAGE_CMD_GET_GB28181PARAM = 396; // GB28181参数 + int MESSAGE_CMD_SET_GB28181PARAM = 397; // GB28181参数 + int MESSAGE_CMD_GET_REGIONTEMPPARAM_EX2 = 398; // 区域测温参数(支持24个区域) + int MESSAGE_CMD_SET_REGIONTEMPPARAM_EX2 = 399; // 区域测温参数(支持24个区域) + int MESSAGE_CMD_GET_POLYGONTEMPPARAM_EX = 400; // 多边形测温参数(支持24个区域) + int MESSAGE_CMD_SET_POLYGONTEMPPARAM_EX = 401; // 多边形测温参数(支持24个区域) + int MESSAGE_CMD_GET_SMARTANALYSIS_ENABLE = 402; // 智能分析功能使能 + int MESSAGE_CMD_SET_SMARTANALYSIS_ENABLE = 403; // 智能分析功能使能 + int MESSAGE_CMD_GET_SMARTANALYSIS_ALARM = 404; // 智能分析联动报警 + int MESSAGE_CMD_SET_SMARTANALYSIS_ALARM = 405; // 智能分析联动报警 + int MESSAGE_CMD_GET_TEMPOSDMODE = 406; // 温度OSD模式 + int MESSAGE_CMD_SET_TEMPOSDMODE = 407; // 温度OSD模式 + int MESSAGE_CMD_GET_GPSINFO_ABIF = 408; // GPS信息(ABIF) + int MESSAGE_CMD_GET_CENTER_OSD = 409; // 中心点OSD使能 + int MESSAGE_CMD_SET_CENTER_OSD = 410; // 中心点OSD使能 + int MESSAGE_CMD_PARAMDEFAULT_DEEP = 411; // 恢复默认参数(深度) + int MESSAGE_CMD_GET_ONVIFPORT = 412; // Onvif端口号 + int MESSAGE_CMD_SET_ONVIFPORT = 413; // Onvif端口号 + int MESSAGE_CMD_GET_DAYNIGHT_STATE = 414; // 日夜状态 + int MESSAGE_CMD_GET_FLAME_DETECT_PARAM = 415; // 火焰检测参数 + int MESSAGE_CMD_SET_FLAME_DETECT_PARAM = 416; // 火焰检测参数 + int MESSAGE_CMD_FLAME_DETECT_PARAM_RESET = 417; // 火焰检测参数复位 + int MESSAGE_CMD_SET_GRIDSPARAM = 418; // 设置宫格参数 + int MESSAGE_CMD_GET_GRIDSPARAM = 419; // 设置宫格参数 + int MESSAGE_CMD_GET_GETREGIONTEMPVALUE_EX2 = 420; // 获取各区域温度值(64个区域) + int MESSAGE_CMD_SET_MANUAL_FOCUS = 421; // 手动聚焦开始 + int MESSAGE_CMD_SET_MANUAL_FOCUS_STOP = 422; // 手动聚焦结束 + int MESSAGE_CMD_GET_FOCUSPOS = 423; // 获取聚焦位置 + int MESSAGE_CMD_SET_FOCUSPOS = 424; // 设置聚焦位置 + int MESSAGE_CMD_SET_FOCUSCTRL = 425; // 自动聚焦控制 + int MESSAGE_CMD_GET_IMGFREEZE = 426; // 获取图像冻结参数 + int MESSAGE_CMD_SET_IMGFREEZE = 427; // 设置图像冻结参数 + int MESSAGE_CMD_GET_EXPOSUREPARAMEX = 428; // 获取曝光参数(扩展) + int MESSAGE_CMD_SET_EXPOSUREPARAMEX = 429; // 设置曝光参数(扩展) + int MESSAGE_CMD_GETVIPARAM = 430; // 获取视频参数 + int MESSAGE_CMD_SETVIPARAM = 431; // 设置视频参数 + int MESSAGE_CMD_GET_AGCPARAM_EX = 432; // 获取红外AGC参数 + int MESSAGE_CMD_SET_AGCPARAM_EX = 433; // 设置红外AGC参数 + int MESSAGE_CMD_GET_TEMPPARAM_EX = 434; // 获取测温相关参数 + int MESSAGE_CMD_SET_TEMPPARAM_EX = 435; // 设置测温相关参数 + int MESSAGE_CMD_GET_GETREGIONTEMPVALUE_EX = 436; // 获取各区域温度值(24个区域) + int MESSAGE_CMD_MAX = 437; // 最大值 + } +} diff --git a/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKStruct.java b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKStruct.java new file mode 100644 index 0000000..5b0c2f8 --- /dev/null +++ b/src/main/java/com/inspect/nvr/jna/lincseek/IRNetSDKStruct.java @@ -0,0 +1,1111 @@ +package com.inspect.nvr.jna.lincseek; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinDef.HWND; + +import java.util.Arrays; +import java.util.List; + +/** + * IRNetSDK JNA 结构体映射(VSNETStructDef.h + IRNet.h 中的结构体)。 + * 所有结构体使用 __stdcall 对齐,通过 {@link com.sun.jna.win32.W32APITypeMapper} 处理。 + * 注意:字符串字段使用 byte[] 以确保编码安全;解码时使用 Native.toString(bytes, "GBK")。 + */ +@SuppressWarnings("unused") +public interface IRNetSDKStruct { + + // ═════════════════════════════════════════════════════════════════════ + // 核心句柄类型 + // ═════════════════════════════════════════════════════════════════════ + + /** + * IRNETHANDLE — 不透明连接句柄(typedef void*) + */ + class IRNETHANDLE extends Pointer { + /** 无效句柄,对应C中的 (IRNETHANDLE)-1,即 (void*)-1 */ + public static final IRNETHANDLE INVALID_HANDLE_VALUE = new IRNETHANDLE(-1); + + public IRNETHANDLE() { super(0); } + public IRNETHANDLE(long peer) { super(peer); } + } + + // ═════════════════════════════════════════════════════════════════════ + // CHANNEL_CLIENTINFO — 客户端通道信息结构 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_sername", "m_username", "m_password", "m_tranType", "m_playstart", + "m_ch", "m_hVideohWnd", "m_hChMsgWnd", "m_nChmsgid", "m_buffnum", + "m_useoverlay", "nColorKey", "url", "m_messagecallback", "context" + }) + class CHANNEL_CLIENTINFO extends Structure { + @Deprecated public String m_sername; // 服务器名 + @Deprecated public String m_username; // 用户名 + @Deprecated public String m_password; // 密码 + public short m_tranType; // 传输类型 + public short m_playstart; // 是否启动预览, 0=不自动启动 + public byte m_ch; // 通道 + public HWND m_hVideohWnd; // 视频窗口句柄(仅Windows) + public HWND m_hChMsgWnd; // 消息窗口句柄 + public int m_nChmsgid; // 消息ID + public int m_buffnum; // 缓冲帧数 + public int m_useoverlay; // 是否使用覆盖 + public int nColorKey; // 颜色键(COLORREF) + public byte[] url = new byte[40]; // 设备URL/IP + public IRNetSDKCallback.CCICallback m_messagecallback; // 消息回调 + public Pointer context; // 用户上下文 + + /** + * 创建通道信息(使用 String 类型,JNA 自动转换为 native 字符串)。 + * 推荐改用 Safe 内部类以避免编码问题。 + */ + public static CHANNEL_CLIENTINFO create( + String sername, String username, String password, + byte channel, HWND videoWnd, HWND msgWnd, int msgId, + IRNetSDKCallback.CCICallback callback, Pointer context) { + CHANNEL_CLIENTINFO info = new CHANNEL_CLIENTINFO(); + info.m_sername = sername; + info.m_username = username; + info.m_password = password; + info.m_tranType = 3; + info.m_playstart = 0; + info.m_ch = channel; + info.m_hVideohWnd = videoWnd; + info.m_hChMsgWnd = msgWnd; + info.m_nChmsgid = msgId; + info.m_buffnum = 10; + info.m_useoverlay = 0; + info.m_messagecallback = callback; + info.context = context; + return info; + } + + /** + * 创建通道信息并填充 url 字段(推荐使用)。 + */ + public static CHANNEL_CLIENTINFO createWithUrl( + String sername, String username, String password, + byte channel, String deviceUrl, HWND videoWnd, HWND msgWnd, int msgId, + IRNetSDKCallback.CCICallback callback, Pointer context) { + CHANNEL_CLIENTINFO info = create(sername, username, password, channel, + videoWnd, msgWnd, msgId, callback, context); + if (deviceUrl != null) { + byte[] urlBytes = deviceUrl.getBytes(); + System.arraycopy(urlBytes, 0, info.url, 0, + Math.min(urlBytes.length, info.url.length)); + } + return info; + } + + @Override + protected List getFieldOrder() { + return Arrays.asList( + "m_sername", "m_username", "m_password", "m_tranType", "m_playstart", + "m_ch", "m_hVideohWnd", "m_hChMsgWnd", "m_nChmsgid", "m_buffnum", + "m_useoverlay", "nColorKey", "url", "m_messagecallback", "context" + ); + } + + /** + * 安全版 CHANNEL_CLIENTINFO:使用 byte[] 存储字符串(避免 JNA String 编码问题)。 + */ + public static class Safe extends Structure { + public byte[] m_sername = new byte[24]; // 设备名 + public byte[] m_username = new byte[20]; // 用户名 + public byte[] m_password = new byte[20]; // 密码 + public short m_tranType; // 传输类型 + public short m_playstart; // 是否启动预览 + public byte m_ch; // 通道 + public HWND m_hVideohWnd; // 视频窗口句柄 + public HWND m_hChMsgWnd; // 消息窗口句柄 + public int m_nChmsgid; // 消息ID + public int m_buffnum; // 缓冲帧数 + public int m_useoverlay; // 是否使用覆盖 + public int nColorKey; // 颜色键 + public byte[] url = new byte[40]; // URL + public IRNetSDKCallback.CCICallback m_messagecallback; // 消息回调 + public Pointer context; // 用户上下文 + + @Override + protected List getFieldOrder() { + return Arrays.asList( + "m_sername", "m_username", "m_password", "m_tranType", "m_playstart", + "m_ch", "m_hVideohWnd", "m_hChMsgWnd", "m_nChmsgid", "m_buffnum", + "m_useoverlay", "nColorKey", "url", "m_messagecallback", "context" + ); + } + } + } + + // ═════════════════════════════════════════════════════════════════════ + // DEV_ENV_INFO — 设备测温环境信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "fEmissivity", "fWinTrans", "fWinTemp", "fWinRefl", "fReflTemp", + "fAtmTrans", "fAtmTemp", "fBkgTemp", "fDistance", "fHumidity", + "fRadRate", "fEnvTemp", "osdena" + }) + class DEV_ENV_INFO extends Structure { + public float fEmissivity; // 物体发射率(0-1) + public float fWinTrans; // 窗口透射率(0-1) + public float fWinTemp; // 窗口温度[K] + public float fWinRefl; // 窗口反射率(0-1) + public float fReflTemp; // 窗口反射温度[K] + public float fAtmTrans; // 大气透射率(0-1) + public float fAtmTemp; // 大气温度[K] + public float fBkgTemp; // 背景温度[K] + public float fDistance; // 距离[m] + public float fHumidity; // 相对湿度 + public float fRadRate; // 辐射率[0-1] + public float fEnvTemp; // 环境温度[℃] + public int osdena; // 水印使能 + + public DEV_ENV_INFO() {} + public DEV_ENV_INFO(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // DEV_TEMP_SPAN — 设备温跨控制 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"fTempMin", "fTempMax", "bAuto"}) + class DEV_TEMP_SPAN extends Structure { + public float fTempMin; // 最小温度[℃] + public float fTempMax; // 最大温度[℃] + public int bAuto; // 自动控制 (TRUE=自动, 忽略fTempMin/fTempMax) + + public DEV_TEMP_SPAN() {} + public DEV_TEMP_SPAN(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // FFFTEMPERATUREDATA — JPEG回调中的温度数据结构 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"temperatueData", "width", "height"}) + class FFF_TEMPERATURE_DATA extends Structure { + public Pointer temperatueData; // float* — 温度数据首地址 + public short width; // 图像宽 + public short height; // 图像高 + + public FFF_TEMPERATURE_DATA() {} + public FFF_TEMPERATURE_DATA(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // LI_INTRUSION_AREA — 入侵区域 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"usX", "usY", "usWidth", "usHeight"}) + class LI_INTRUSION_AREA extends Structure { + public short usX; // 左上角X坐标 + public short usY; // 左上角Y坐标 + public short usWidth; // 区域宽度(像素) + public short usHeight; // 区域高度(像素) + + public LI_INTRUSION_AREA() {} + public LI_INTRUSION_AREA(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // RVSINFOREG — 转发服务绑定注册信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_rvsbindurl", "m_rvsbindport"}) + class RVSINFOREG extends Structure { + public String m_rvsbindurl; // RVS绑定URL, NULL表示所有URL + public short m_rvsbindport; // RVS绑定端口 + } + + // ═════════════════════════════════════════════════════════════════════ + // IRNET_REDIRECTORINFO — 转发器服务信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_multiip", "m_wMultiPort", "m_wLocaport", "m_videobuff", + "m_audiobuff", "m_channuser", "m_totaluser", + "m_UserCheckcallback", "m_UserConnectcallback" + }) + class IRNET_REDIRECTORINFO extends Structure { + public byte[] m_multiip = new byte[16]; // 多播IP地址 + public short m_wMultiPort; // 多播端口 + public short m_wLocaport; // 本地端口 + public int m_videobuff; // 视频缓冲区数 + public int m_audiobuff; // 音频缓冲区数 + public int m_channuser; // 每通道用户数 + public int m_totaluser; // 总用户数 + public IRNetSDKCallback.UserCheckCallback m_UserCheckcallback; // 用户校验回调 + public IRNetSDKCallback.UserConnectCallback m_UserConnectcallback; // 用户登录注销回调 + } + + // ═════════════════════════════════════════════════════════════════════ + // DEVICE_BASE_INFO — 设备基本信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"servername", "username", "password", "url", "wserport"}) + class DEVICE_BASE_INFO extends Structure { + public String servername; // 设备名 + public String username; // 登录用户名 + public String password; // 登录密码 + public String url; // 设备IP + public short wserport; // 端口号(通常3000) + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_HEADAREA — 人头检测区域 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"iDetId", "x", "y", "w", "h", "temp"}) + class VSNET_HEADAREA extends Structure { + public int iDetId; // 检测ID + public int x; // 左上角X + public int y; // 左上角Y + public int w; // 宽度 + public int h; // 高度 + public float temp; // 温度 + + public VSNET_HEADAREA() {} + public VSNET_HEADAREA(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_TED_CORRECTION_S — 人体测温距离校正参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_headbox_type", "m_To", "m_b", "m_m"}) + class VSNET_TED_CORRECTION_S extends Structure { + public int m_headbox_type; // VSNET_HEADBOX_SIZE_TYPE + public float m_To; + public float m_b; + public float m_m; + + public VSNET_TED_CORRECTION_S() {} + public VSNET_TED_CORRECTION_S(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSSERIAL_INFO — 串口参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"baudrate", "databit", "stopbit", "checkbit", "flowcontrol"}) + class VSSERIAL_INFO extends Structure { + public int baudrate; // 波特率 + public byte databit; // 数据位: 5,6,7,8 + public byte stopbit; // 停止位: 1,2 + public byte checkbit; // 校验位: 0=无校验, 1=奇校验, 2=偶校验, 3=固定为1, 4=固定为0 + public byte flowcontrol; // 流控: 0=无流控, 1=软流控, 2=硬流控 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSTREAMINFO — 码流信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_videotag", "m_width", "m_height", "m_bhaveaudio", + "m_samplesize", "m_audiotag", "m_audiobitrate" + }) + class VSTREAMINFO extends Structure { + public int m_videotag; // 视频标签 + public short m_width; // 宽 + public short m_height; // 高 + public int m_bhaveaudio; // 是否有音频 + public int m_samplesize; // 音频采样频率 + public short m_audiotag; // 音频标签 + public short m_audiobitrate; // 音频码率 + + public VSTREAMINFO() {} + public VSTREAMINFO(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPVALUE — 温度值 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_maxtemp", "m_mintemp", "m_avgtemp"}) + class VSNET_TEMP_VALUE extends Structure { + public float m_maxtemp; // 最大值 + public float m_mintemp; // 最小值 + public float m_avgtemp; // 平均值 + + public VSNET_TEMP_VALUE() {} + public VSNET_TEMP_VALUE(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETCOORDVALUE — 坐标+温度值 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_temp_value", "m_temp_x", "m_temp_y"}) + class VSNET_COORD_VALUE extends Structure { + public float m_temp_value; // 温度值 + public int m_temp_x; // 温度X坐标 + public int m_temp_y; // 温度Y坐标 + + public VSNET_COORD_VALUE() {} + public VSNET_COORD_VALUE(Pointer p) { super(p); read(); } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPVALUE_EX — 扩展温度值信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_maxtempinfo", "m_mintempinfo", "m_avgtempinfo"}) + class VSNET_TEMP_VALUE_EX extends Structure { + public VSNET_COORD_VALUE m_maxtempinfo; // 最高温信息 + public VSNET_COORD_VALUE m_mintempinfo; // 最低温信息 + public float m_avgtempinfo; // 平均温 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETWIFISSIDINFO — WiFi SSID信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_wifissid", "m_wifiencmode"}) + class VSNET_WIFI_SSID_INFO extends Structure { + public byte[] m_wifissid = new byte[40]; // SSID名称 + public int m_wifiencmode; // 加密模式 0=无加密 1=WEP 2=WPA-PSK/WPA2-PSK + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETWIFISSIDLIST — WiFi SSID列表 (MAX_SSIDNUM = 40) + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_ssidnum", "m_ssidinfo"}) + class VSNET_WIFI_SSID_LIST extends Structure { + public int m_ssidnum; // 搜索到的无线路由器数量 + public VSNET_WIFI_SSID_INFO[] m_ssidinfo = new VSNET_WIFI_SSID_INFO[IRNetSDKConst.MAX_SSIDNUM]; + + public VSNET_WIFI_SSID_LIST() { + for (int i = 0; i < IRNetSDKConst.MAX_SSIDNUM; i++) { + m_ssidinfo[i] = new VSNET_WIFI_SSID_INFO(); + } + } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETREGIONTEMPAREA — 区域测温参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_region_enable", "m_osd_enable", "m_cursor_enable", "m_param_enable", + "m_x", "m_y", "m_width", "m_height", "m_detectdist", "m_radrate" + }) + class VSNET_REGION_TEMP_AREA extends Structure { + public int m_region_enable; // 区域测温使能 + public int m_osd_enable; // 测温OSD使能 + public int m_cursor_enable; // 测温高低光标功能使能 + public int m_param_enable; // 区域使用本地参数(?) + public short m_x; // X + public short m_y; // Y + public short m_width; // 宽 + public short m_height; // 高 + public float m_detectdist; // 目标距离(m) + public float m_radrate; // 辐射率[0,1] + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPALARMPARAM — 测温报警参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_enable", "m_typethreshold", "m_htempthreshold", "m_ltempthreshold", + "m_singlehost", "m_record", "m_out", "m_enpreno", "m_preno", + "m_capjpeg", "m_timelist" + }) + class VSNET_TEMP_ALARM_PARAM extends Structure { + public int m_enable; // 功能使能 + public int m_typethreshold; // 测温方式: 0:>上限, 1:<下限, 2:[下限,上限], 3:不在[下限,上限] + public float m_htempthreshold; // 温度报警上限 + public float m_ltempthreshold; // 温度报警下限 + public int m_singlehost; // 中心上传标志 + public byte[] m_record = new byte[16]; // 关联录像 + public byte[] m_out = new byte[8]; // 关联输出 1:ON, 0:OFF + public byte[] m_enpreno = new byte[16]; // 关联预置点 + public byte[] m_preno = new byte[16]; // 被调预置点号 + public byte[] m_capjpeg = new byte[16]; // 关联抓图 + public TIMELIST m_timelist; // 检测时间表 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPALARMPARAMEX — 扩展测温报警参数(5级报警) + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_enable", "m_typethreshold", "m_htempthreshold", "m_ltempthreshold", + "m_singlehost", "m_record", "m_out", "m_enpreno", "m_preno", + "m_capjpeg", "m_timelist", "m_high_level", "m_low_level", "m_s32Reserve" + }) + class VSNET_TEMP_ALARM_PARAM_EX extends Structure { + public int m_enable; + public int m_typethreshold; + public float m_htempthreshold; + public float m_ltempthreshold; + public int m_singlehost; + public byte[] m_record = new byte[16]; + public byte[] m_out = new byte[8]; + public byte[] m_enpreno = new byte[16]; + public byte[] m_preno = new byte[16]; + public byte[] m_capjpeg = new byte[16]; + public TIMELIST m_timelist; + public float[] m_high_level = new float[5]; // 等级1~5 (高温) + public float[] m_low_level = new float[5]; // 等级1~5 (低温) + public int[] m_s32Reserve = new int[3]; // 保留 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETSENSORSTATE — Sensor状态 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_NUCTableIdx", "m_DevState", "m_CaptureFlag", "m_TempMeasurementStatus", + "m_FPA", "m_FPASpeed", "m_humancali_state", "m_LastFFCTime", + "m_s16Reserve", "m_s32Reserve" + }) + class VSNET_SENSOR_STATE extends Structure { + public byte m_NUCTableIdx; // NUC表段索引[0~4] + public byte m_DevState; // 设备状态: -1=未知, 0=稳定, 1=不稳定 + public byte m_CaptureFlag; // 抓拍标志: 0=不抓拍, 1=正在抓拍 + public byte m_TempMeasurementStatus; // 测温状态: 0=可测温, 1=不可测温 + public int m_FPA; // 当前FPA x100 (℃) + public int m_FPASpeed; // FPA变化速度 x1000 (℃/min) + public VSNET_HUMANCALI_STATE_S m_humancali_state; // 人体校准状态 + public short m_LastFFCTime; // 距离上次FFC时间 (秒) + public short m_s16Reserve; // 保留 + public int[] m_s32Reserve = new int[2];// 保留 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_HUMANCALI_STATE_S — 人体校准状态 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_state", "m_errcode"}) + class VSNET_HUMANCALI_STATE_S extends Structure { + public int m_state; // VSNET_HUMANCALI_STATE_E + public int m_errcode; // VSNET_HUMANCALI_ERRCODE_E + } + + // ═════════════════════════════════════════════════════════════════════ + // TIMECHECK — 时间检测段 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_starthour", "m_startmin", "m_stophour", "m_stopmin", "m_maskweek", "bReceive"}) + class TIMECHECK extends Structure { + public byte m_starthour; // 开始时 + public byte m_startmin; // 开始分 + public byte m_stophour; // 结束时 + public byte m_stopmin; // 结束分 + public byte m_maskweek; // 每周各天: bit0=周日, bit1=周一...bit6=周六 + public byte[] bReceive = new byte[3]; // 保留 + } + + // ═════════════════════════════════════════════════════════════════════ + // TIMELIST — 7天时间表 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"pList"}) + class TIMELIST extends Structure { + public TIMECHECK[] pList = new TIMECHECK[7]; // 时间表 + + public TIMELIST() { + for (int i = 0; i < 7; i++) pList[i] = new TIMECHECK(); + } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETSTREAMINFO_S — 通道带宽信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_bandwidthRecv", "m_bandwidthRecvAv"}) + class VSNET_STREAMINFO_S extends Structure { + public int[][] m_bandwidthRecv = new int[IRNetSDKConst.VSNET_DVR_MAXCH][IRNetSDKConst.VSNET_DVR_MAXSTM]; // 通道实时接收带宽 (Bps) + public int[][] m_bandwidthRecvAv = new int[IRNetSDKConst.VSNET_DVR_MAXCH][IRNetSDKConst.VSNET_DVR_MAXSTM]; // 通道平均接收带宽 (Bps) + } + + // ═════════════════════════════════════════════════════════════════════ + // ONEUSER — 用户凭证 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_username", "m_password"}) + class ONEUSER extends Structure { + public byte[] m_username = new byte[20]; // 用户名 + public byte[] m_password = new byte[20]; // 密码 + } + + // ═════════════════════════════════════════════════════════════════════ + // WHOLEUSER — 完整用户组 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_admin", "hl_operator", "m_operator"}) + class WHOLEUSER extends Structure { + public ONEUSER m_admin; // 管理员 + public ONEUSER[] hl_operator = new ONEUSER[10]; // 高级操作员 + public ONEUSER[] m_operator = new ONEUSER[10]; // 操作员 + + public WHOLEUSER() { + m_admin = new ONEUSER(); + for (int i = 0; i < 10; i++) { hl_operator[i] = new ONEUSER(); m_operator[i] = new ONEUSER(); } + } + } + + // ═════════════════════════════════════════════════════════════════════ + // WHOLEPARAM — 设备全局参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_servername", "m_serverip", "m_servermask", "m_gatewayAddr", + "m_dnsaddr", "m_multiAddr", "m_serport", "m_mulport", "m_webport", + "m_isPAL", "m_launage", "m_phyAddr", "m_reserved", "m_serial", + "m_ddns", "m_version" + }) + class WHOLEPARAM extends Structure { + public byte[] m_servername = new byte[24]; // 服务器名 + public byte[] m_serverip = new byte[16]; // IP地址 + public byte[] m_servermask = new byte[16]; // 子网掩码 + public byte[] m_gatewayAddr = new byte[16]; // 网关 + public byte[] m_dnsaddr = new byte[16]; // DNS + public byte[] m_multiAddr = new byte[16]; // 多播地址 + public short m_serport; // 数据端口 + public short m_mulport; // 多播端口 + public short m_webport; // Web端口 + public byte m_isPAL; // 视频制式(PAL/NTSC) + public byte m_launage; // 语言 + public byte[] m_phyAddr = new byte[6]; // 物理地址 + public short m_reserved; // 保留 + public byte[] m_serial = new byte[8]; // 序列号 + public WHOLE_DDNS m_ddns; // DDNS参数 + public VERSIONINFO m_version; // 版本信息 + } + + // ═════════════════════════════════════════════════════════════════════ + // WHOLE_DDNS — DDNS配置 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"bUseDDNS", "DDNSSerIp", "DDNSSerPort", "LocalMapPort"}) + class WHOLE_DDNS extends Structure { + public int bUseDDNS; // DDNS使能 + public byte[] DDNSSerIp = new byte[40]; // DDNS服务器IP + public short DDNSSerPort; // DDNS服务器端口 + public short LocalMapPort; // 本地映射端口 + } + + // ═════════════════════════════════════════════════════════════════════ + // VERSIONINFO — 设备版本信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"pStrBSPVer", "pStrAPPVer", "pStrBSPBuildTime", "pStrAPPBuildTime"}) + class VERSIONINFO extends Structure { + public byte[] pStrBSPVer = new byte[50]; // BSP版本 + public byte[] pStrAPPVer = new byte[50]; // 应用版本 + public byte[] pStrBSPBuildTime = new byte[50]; // BSP编译时间 + public byte[] pStrAPPBuildTime = new byte[50]; // 应用编译时间 + } + + // ═════════════════════════════════════════════════════════════════════ + // CHANNELPARAM — 通道编码参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_channelName", "m_streamType", "m_encodeType", "m_Iinterval", + "m_videoFrameRate", "m_bitratetype", "m_maxqueue", "m_minqueue", + "m_maxbitrates", "m_audiosample", "m_audiobitrate", "m_delay", + "m_benrecord", "m_record" + }) + class CHANNELPARAM extends Structure { + public byte[] m_channelName = new byte[16]; // 通道名称 + public int m_streamType; // 流类型: 0=视频流, 1=视音频流 + public int m_encodeType; // 编码分辨率 + public int m_Iinterval; // I帧间隔(10-200) + public int m_videoFrameRate; // 帧率 + public int m_bitratetype; // 码率类型: 0=定码率, 1=变码率 + public int m_maxqueue; // VBR量化系数(2-31) + public int m_minqueue; // CBR量化系数(2-31) + public int m_maxbitrates; // CBR最大码率(64K-8000K) + public int m_audiosample; // 音频采样频率 + public int m_audiobitrate; // 音频压缩码率 + public int m_delay; // 报警延时 + public int m_benrecord; // 定时录像使能 + public TIMELIST m_record; // 定时录像时间表 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETREGIONTEMP — 区域温度信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_enable", "m_max", "m_min", "m_avg"}) + class VSNET_REGION_TEMP extends Structure { + public int m_enable; // 区域温度使能 + public VSNET_REGION m_max; // 最高温值 + public VSNET_REGION m_min; // 最低温值 + public VSNET_REGION m_avg; // 平均值 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETREGION — 区域坐标+温度值 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_valid", "m_val", "m_x", "m_y"}) + class VSNET_REGION extends Structure { + public short m_valid; // 1=有效 0=无效 + public short m_val; // T * 10 (温度×10) + public short m_x; // X坐标 + public short m_y; // Y坐标 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETCOORDINFO — 坐标信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"min_x", "min_y", "max_x", "max_y"}) + class VSNET_COORD_INFO extends Structure { + public int min_x; // 最低温X + public int min_y; // 最低温Y + public int max_x; // 最高温X + public int max_y; // 最高温Y + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPDATA — 温度数据 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_ir_avgtemp", "m_ir_hightemp", "m_ir_lowtemp", "m_ir_high", "m_ir_low"}) + class VSNET_TEMP_DATA extends Structure { + public float m_ir_avgtemp; // 红外平均温度 + public float m_ir_hightemp; // 红外最高温度 + public float m_ir_lowtemp; // 红外最低温度 + public float m_ir_high; // 温度段最高温 + public float m_ir_low; // 温度段最低温 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETRADPARAM — 辐射参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_essivity", "m_bkgtmp", "m_atmktmp", "m_wintmp", + "m_wintrans", "m_atmtrans", "m_humidity", "m_lenstrans", "m_lensfnum" + }) + class VSNET_RAD_PARAM extends Structure { + public float m_essivity; // 发射率 + public float m_bkgtmp; // 环境温度 + public float m_atmktmp; // 大气温度 + public float m_wintmp; // 窗口温度 + public float m_wintrans; // 窗口透过率 + public float m_atmtrans; // 大气透过率 + public float m_humidity; // 相对湿度 + public float m_lenstrans; // 镜头透过率 + public float m_lensfnum; // 镜头F值 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETDISKSTATE — 硬盘状态 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_hds", "m_hdtype", "m_hdstate", "m_totalsize", "m_freesize"}) + class VSNET_DISK_STATE extends Structure { + public int m_hds; // 硬盘总数 + public int[] m_hdtype = new int[8]; // 硬盘类型 + public int[] m_hdstate = new int[8]; // 硬盘状态 0xff=错误 0xfe=无硬盘 + public int[] m_totalsize = new int[8]; // 硬盘总空间 + public int[] m_freesize = new int[8]; // 硬盘剩余空间 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPCALIBPARAM — 测温校准参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_emissivity", "m_winTrans", "m_winTemp", "m_winRefl", + "m_reflTemp", "m_atmTrans", "m_atmTemp", "m_bkgTemp" + }) + class VSNET_TEMP_CALIB_PARAM extends Structure { + public float m_emissivity; // 物体发射率 + public float m_winTrans; // 窗口透过率 + public float m_winTemp; // 窗口温度[K] + public float m_winRefl; // 窗口反射率 + public float m_reflTemp; // 窗口反射温度[K] + public float m_atmTrans; // 大气透过率 + public float m_atmTemp; // 大气温度[K] + public float m_bkgTemp; // 背景温度[K] + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETAGCPARAM — AGC参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_enable", "m_hightemp", "m_lowtemp"}) + class VSNET_AGC_PARAM extends Structure { + public int m_enable; // 手动使能 + public float m_hightemp; // 高温阈值 + public float m_lowtemp; // 低温阈值 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETIMAGEFUSEPARAM — 图像融合参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_enable", "m_strength"}) + class VSNET_IMAGE_FUSE_PARAM extends Structure { + public int m_enable; // 融合功能使能 0:关 1:开 + public int m_strength; // 融合强度 0:低 1:中 2:高 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETIMAGEFUSEOFFSET — 融合偏移量 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_horiz_offset", "m_vert_offset"}) + class VSNET_IMAGE_FUSE_OFFSET extends Structure { + public int m_horiz_offset; // 水平偏移 + public int m_vert_offset; // 垂直偏移 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPPARAM_EX — 测温相关参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_envtemp", "m_detectdist", "m_radrate", "m_humidity"}) + class VSNET_TEMP_PARAM_EX extends Structure { + public float m_envtemp; // 环境温度[℃] + public float m_detectdist; // 检测距离[m] + public float m_radrate; // 辐射率[0,1] + public float m_humidity; // 湿度[0,100]% + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETREGIONTEMPPARAM — 区域测温参数(8区域) + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_region"}) + class VSNET_REGION_TEMP_PARAM extends Structure { + public VSNET_REGION_TEMP_AREA[] m_region = new VSNET_REGION_TEMP_AREA[IRNetSDKConst.REGIONTEMPNUM]; + + public VSNET_REGION_TEMP_PARAM() { + for (int i = 0; i < IRNetSDKConst.REGIONTEMPNUM; i++) { + m_region[i] = new VSNET_REGION_TEMP_AREA(); + } + } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETREGIONTTEMPVALUE — 区域温度值(8区域) + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_region_temp"}) + class VSNET_REGION_TEMP_VALUES extends Structure { + public VSNET_TEMP_VALUE[] m_region_temp = new VSNET_TEMP_VALUE[IRNetSDKConst.REGIONTEMPNUM]; + + public VSNET_REGION_TEMP_VALUES() { + for (int i = 0; i < IRNetSDKConst.REGIONTEMPNUM; i++) { + m_region_temp[i] = new VSNET_TEMP_VALUE(); + } + } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNETTEMPCOORDINFO — 温度坐标信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_global_coord", "m_region_coord"}) + class VSNET_TEMP_COORD_INFO extends Structure { + public VSNET_COORD_INFO m_global_coord; // 全局高低温坐标 + public VSNET_COORD_INFO[] m_region_coord = new VSNET_COORD_INFO[IRNetSDKConst.REGIONTEMPNUM]; // 区域高低温坐标 + + public VSNET_TEMP_COORD_INFO() { + m_global_coord = new VSNET_COORD_INFO(); + for (int i = 0; i < IRNetSDKConst.REGIONTEMPNUM; i++) { + m_region_coord[i] = new VSNET_COORD_INFO(); + } + } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_VIDEO_MASK_AREA — 视频遮挡区域 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_x", "m_y", "m_width", "m_height"}) + class VSNET_VIDEO_MASK_AREA extends Structure { + public short m_x; + public short m_y; + public short m_width; + public short m_height; + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_VIDEO_MASK — 视频遮挡(4个区域) + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_bmask", "m_maskarea"}) + class VSNET_VIDEO_MASK extends Structure { + public int m_bmask; // 图像遮挡使能 + public VSNET_VIDEO_MASK_AREA[] m_maskarea = new VSNET_VIDEO_MASK_AREA[4]; // 遮挡区域 + + public VSNET_VIDEO_MASK() { + for (int i = 0; i < 4; i++) m_maskarea[i] = new VSNET_VIDEO_MASK_AREA(); + } + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_DAYNIGHTSWITCH — 日夜切换参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_daynight", "m_daynight_mode", "m_handblackwhite", + "m_autoblackwhite", "m_lux" + }) + class VSNET_DAYNIGHT_SWITCH extends Structure { + public VSNET_DAYNIGHT_TIME[] m_daynight = new VSNET_DAYNIGHT_TIME[2]; // 日夜时间 + public int m_daynight_mode; // 0:手动, 1:按时间, 2:自动 + public int m_handblackwhite; // 手动模式: 0:彩色, 1:黑白 + public int m_autoblackwhite; // 自动模式: 0:光触发IR_CUT, 1:内触发 + public int m_lux; // 照度阈值 + + public VSNET_DAYNIGHT_SWITCH() { + for (int i = 0; i < 2; i++) m_daynight[i] = new VSNET_DAYNIGHT_TIME(); + } + } + + @Structure.FieldOrder({"m_Hour", "m_Min", "m_Sec", "m_Type"}) + class VSNET_DAYNIGHT_TIME extends Structure { + public int m_Hour; // 时 + public int m_Min; // 分 + public int m_Sec; // 秒 + public int m_Type; // 0:转夜, 1:夜转昼 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_NOISE_MODE_PARAM / VSNET_NOISE_PARAM — 降噪参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_noise", "m_wdrmode"}) + class VSNET_NOISE_MODE_PARAM extends Structure { + public VSNET_NOISE_PARAM m_noise; // 降噪参数 + public int m_wdrmode; // Sensor模式: 0=linear, 1=WDR + } + + @Structure.FieldOrder({"m_noisemode", "m_noiseenable", "m_noiselevel"}) + class VSNET_NOISE_PARAM extends Structure { + public int m_noisemode; // 降噪模式 0:自动 1:手动 + public int m_noiseenable; // 降噪开关 0:OFF 1:ON + public int m_noiselevel; // 降噪等级 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_ENC_VPP — 视频预处理参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_nVppmode", "m_nIeSth", "m_nSpSth", "m_nDnSfCosSth", "m_nDnSfIncSth", "m_nDnTfSth"}) + class VSNET_ENC_VPP extends Structure { + public int m_nVppmode; // VPP模式: 0=关闭 1=自动 2=低照度 3=增强 4=手动 + public int m_nIeSth; // IE强度 [0,10] + public int m_nSpSth; // SP强度 [-4,5] + public int m_nDnSfCosSth; // 粗粒度空域降噪强度 [0,3] + public int m_nDnSfIncSth; // 细粒度空域降噪强度 [0,255] + public int m_nDnTfSth; // 时域降噪强度 [0,4] + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_GAIN_MODE — 增益模式 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_gaintype", "m_gainmode"}) + class VSNET_GAIN_MODE extends Structure { + public int m_gaintype; // 增益切换控制: 0=自动, 1=手动 + public int m_gainmode; // 增益模式: 1=高增益, 2=低增益 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_SWITCH_MODE — 校准模式切换 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_mode"}) + class VSNET_SWITCH_MODE extends Structure { + public int m_mode; // 0=监控模式, 1=校准模式, 2=测试模式 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_VIDEO_OUT_MODE — 视频输出模式 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_videoout_mode"}) + class VSNET_VIDEO_OUT_MODE extends Structure { + public int m_videoout_mode; // 0=可见光, 1=PIP, 2=红外 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_FFC_MODE — FFC模式 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_mode"}) + class VSNET_FFC_MODE extends Structure { + public int m_mode; // 0=手动, 1=自动, 2=外部 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_FFC_FRAME_PARAM — FFC帧数参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_frame"}) + class VSNET_FFC_FRAME_PARAM extends Structure { + public int m_frame; // 帧数 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_FFC_TEMP_PARAM — FFC温度参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_temp"}) + class VSNET_FFC_TEMP_PARAM extends Structure { + public int m_temp; // 温度 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_DENOISE_PARAM — 降噪参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_denoise"}) + class VSNET_DENOISE_PARAM extends Structure { + public int m_denoise; // [0,100] + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_SENSOR_TEMP — Sensor温度 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_shuttertemp", "m_lenstemp", "m_iboardtemp", "m_sboardtemp"}) + class VSNET_SENSOR_TEMP extends Structure { + public float m_shuttertemp; // shutter温度 + public float m_lenstemp; // 镜头温度 + public float m_iboardtemp; // i板温度 + public float m_sboardtemp; // s板温度 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_CAMERA_INFO — 相机信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_sn", "m_pn", "m_ver", "m_devsn", "m_devpn"}) + class VSNET_CAMERA_INFO extends Structure { + public byte[] m_sn = new byte[20]; // 序列号 + public byte[] m_pn = new byte[20]; // 产品号 + public byte[] m_ver = new byte[20]; // 版本 + public byte[] m_devsn = new byte[20]; // 设备序列号 + public byte[] m_devpn = new byte[20]; // 设备产品号 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_THRESHOLD_ALARM_PARAM — 阈值报警参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_enable", "m_typethreshold", "m_thresholdvalue", "m_duration", + "m_singlehost", "m_record", "m_out", "m_enpreno", "m_preno", + "m_capjpeg", "m_timelist" + }) + class VSNET_THRESHOLD_ALARM_PARAM extends Structure { + public int m_enable; // 使能 + public int m_typethreshold; // 0=差值, 1=比值, 2=平均值 + public float m_thresholdvalue; // 阈值[1,100]℃ + public int m_duration; // 持续时间[1,24]小时 + public int m_singlehost; + public byte[] m_record = new byte[16]; + public byte[] m_out = new byte[8]; + public byte[] m_enpreno = new byte[16]; + public byte[] m_preno = new byte[16]; + public byte[] m_capjpeg = new byte[16]; + public TIMELIST m_timelist; + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_OBJ_FLUX_RANGE — 目标辐射范围 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_OBJTemp", "m_ErrRange", "m_GainMode", "m_MinFlux", "m_MaxFlux"}) + class VSNET_OBJ_FLUX_RANGE extends Structure { + public short m_OBJTemp; // 目标温度[0~450]℃ + public byte m_ErrRange; // 误差范围 + public byte m_GainMode; // 0=当前增益, 1=高增益, 2=低增益 + public short m_MinFlux; // 最小辐射值 + public short m_MaxFlux; // 最大辐射值 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_RECORD_PARAM — 录像参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_packet_type", "m_packet_size", "m_packet_time", + "m_hdisk_reserved_size", "m_hdisk_full_alarm", "m_hdisk_full_action" + }) + class VSNET_RECORD_PARAM extends Structure { + public int m_packet_type; // 打包类型: 0=按文件大小, 1=按时间 + public int m_packet_size; // 打包大小(MB) + public int m_packet_time; // 打包时间(分钟) + public int m_hdisk_reserved_size; // 硬盘预留空间(MB) + public int m_hdisk_full_alarm; // 硬盘满报警 + public int m_hdisk_full_action; // 满盘动作: 1=循环覆盖, 0=停止录像 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_WIFI_PARAM — WiFi参数 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_usewifi", "m_wifiipaddr", "m_wifinetmask", "m_wifigateway", + "m_wifidns", "m_wifissid", "m_wifiencmode", "m_wifipwd" + }) + class VSNET_WIFI_PARAM extends Structure { + public int m_usewifi; // 是否使用WiFi + public byte[] m_wifiipaddr = new byte[16]; // 无线IP + public byte[] m_wifinetmask = new byte[16]; // 无线掩码 + public byte[] m_wifigateway = new byte[16]; // 无线网关 + public byte[] m_wifidns = new byte[16]; // 无线DNS + public byte[] m_wifissid = new byte[40]; // SSID + public int m_wifiencmode; // 加密模式 + public byte[] m_wifipwd = new byte[64]; // 密钥 + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_UPNP_INFO — UPNP信息 + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({ + "m_ip", "m_webport", "m_webportout", "m_webportstatus", + "m_rtspport", "m_rtspportout", "m_rtspportstatus", + "m_msgport", "m_msgportout", "m_msgportstatus", + "m_videoport", "m_videoportout", "m_videoportstatus", + "m_fileoptport", "m_fileoptportout", "m_fileoptportstatus", + "m_reserve" + }) + class VSNET_UPNP_INFO extends Structure { + public byte[] m_ip = new byte[16]; + public short m_webport; + public short m_webportout; + public short m_webportstatus; + public short m_rtspport; + public short m_rtspportout; + public short m_rtspportstatus; + public short m_msgport; + public short m_msgportout; + public short m_msgportstatus; + public short m_videoport; + public short m_videoportout; + public short m_videoportstatus; + public short m_fileoptport; + public short m_fileoptportout; + public short m_fileoptportstatus; + public short m_reserve; + } + + // ═════════════════════════════════════════════════════════════════════ + // VSNET_DEVICE_PARAM — 设备参数(tau设备信息) + // ═════════════════════════════════════════════════════════════════════ + + @Structure.FieldOrder({"m_startupTemp", "m_fpaTemp", "m_housingTemp"}) + class VSNET_DEVICE_PARAM extends Structure { + public float m_startupTemp; // 启动温度[℃] + public float m_fpaTemp; // FPA温度[℃] + public float m_housingTemp; // 机壳温度[℃] + } +} diff --git a/src/main/java/com/inspect/nvr/service/CommonCameraService.java b/src/main/java/com/inspect/nvr/service/CommonCameraService.java index f59bc18..440da00 100644 --- a/src/main/java/com/inspect/nvr/service/CommonCameraService.java +++ b/src/main/java/com/inspect/nvr/service/CommonCameraService.java @@ -21,6 +21,7 @@ import java.nio.file.Paths; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.ReentrantLock; @@ -33,9 +34,9 @@ public class CommonCameraService { // 兜底图路径 static final String IMAGE_CAPTURE_FAILED = "images\\imageCaptureFailed.jpg"; // 抓图保存目录 - static final String FILE_DIR = determineCaptureDirectory(); + public static final String FILE_DIR = determineCaptureDirectory(); // 抓图失败重试次数 - static final int DEFAULT_MAX_RETRIES = 20; + static final int DEFAULT_MAX_RETRIES = 10; // 每个NVR最多4个并发抓图任务 static final int MAX_CONCURRENT_PER_NVR = 4; // 每个NVR对应一个信号量,控制并发数 @@ -43,6 +44,33 @@ public class CommonCameraService { // 每个(ip_chanel)对应一个锁,确保同通道串行 final ConcurrentHashMap channelLockMap = new ConcurrentHashMap<>(); + // 控制信号量和并发数 + T withConcurrencyControl(NvrInfo nvrInfo, int channel, Callable task) { + String ip = nvrInfo.getNvrIp(); + Semaphore nvrSemaphore = getOrCreateSemaphore(ip); + ReentrantLock channelLock = getOrCreateLock(ip, channel); + // 1.先获取该NVR的全局并发许可 + nvrSemaphore.acquireUninterruptibly(); + try { + // 2.再获取该通道的独占锁(保证同一通道串行) + channelLock.lock(); + try { + return task.call(); + } catch (Exception e) { + log.error("任务执行异常:", e); + return null; + } finally { + // 必须先unlock通道锁,再释放NVR全局许可 + if (channelLock.isHeldByCurrentThread()) { + channelLock.unlock(); + } + } + } finally { + // 3.释放NVR全局许可 + nvrSemaphore.release(); + } + } + /** * 抓图失败时,写入兜底图 * 可考虑返回byte[] @@ -159,7 +187,9 @@ public class CommonCameraService { */ private static String determineCaptureDirectory() { String os = System.getProperty("os.name").toLowerCase(); + log.info("当前操作系统: {}", os); String userDir = System.getProperty("user.dir"); + log.info("userDir: {}", userDir); if (os.contains("win")) { return "D:/captures/"; diff --git a/src/main/java/com/inspect/nvr/service/DahuaCameraService.java b/src/main/java/com/inspect/nvr/service/DahuaCameraService.java index 16b77ca..ead86b9 100644 --- a/src/main/java/com/inspect/nvr/service/DahuaCameraService.java +++ b/src/main/java/com/inspect/nvr/service/DahuaCameraService.java @@ -13,7 +13,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReentrantLock; /** * 大华设备SDK服务 @@ -46,26 +45,7 @@ public class DahuaCameraService extends CommonCameraService { } public byte[] capture(NvrInfo nvrInfo, int channel) { - String ip = nvrInfo.getNvrIp(); - Semaphore nvrSemaphore = getOrCreateSemaphore(ip); - ReentrantLock channelLock = getOrCreateLock(ip, channel); - // 1.先获取该NVR的全局并发许可 - nvrSemaphore.acquireUninterruptibly(); - try { - // 2.再获取该通道的独占锁(保证同一通道串行) - channelLock.lock(); - try { - return captureWithRetry(nvrInfo, channel); - } finally { - // 必须先unlock通道锁,再释放NVR全局许可 - if (channelLock.isHeldByCurrentThread()) { - channelLock.unlock(); - } - } - } finally { - // 3.释放NVR全局许可 - nvrSemaphore.release(); - } + return withConcurrencyControl(nvrInfo, channel, () -> captureWithRetry(nvrInfo, channel)); } private byte[] captureWithRetry(NvrInfo nvrInfo, int channel) { diff --git a/src/main/java/com/inspect/nvr/service/HikCameraService.java b/src/main/java/com/inspect/nvr/service/HikCameraService.java index a3e2fdf..0b1c90e 100644 --- a/src/main/java/com/inspect/nvr/service/HikCameraService.java +++ b/src/main/java/com/inspect/nvr/service/HikCameraService.java @@ -13,11 +13,13 @@ import javax.annotation.Resource; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; +import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; /** * 海康设备SDK服务 @@ -43,32 +45,6 @@ public class HikCameraService extends CommonCameraService { @Resource private HCNetSDK hcNetSDK; - public T withConcurrencyControl(NvrInfo nvrInfo, int channel, Callable task) { - String ip = nvrInfo.getNvrIp(); - Semaphore nvrSemaphore = getOrCreateSemaphore(ip); - ReentrantLock channelLock = getOrCreateLock(ip, channel); - // 1.先获取该NVR的全局并发许可 - nvrSemaphore.acquireUninterruptibly(); - try { - // 2.再获取该通道的独占锁(保证同一通道串行) - channelLock.lock(); - try { - return task.call(); - } catch (Exception e) { - log.error("[海康]任务执行异常:", e); - return null; - } finally { - // 必须先unlock通道锁,再释放NVR全局许可 - if (channelLock.isHeldByCurrentThread()) { - channelLock.unlock(); - } - } - } finally { - // 3.释放NVR全局许可 - nvrSemaphore.release(); - } - } - /** * 受并发控制的海康抓图 */ diff --git a/src/main/java/com/inspect/nvr/service/LincseekCameraService.java b/src/main/java/com/inspect/nvr/service/LincseekCameraService.java new file mode 100644 index 0000000..db000b7 --- /dev/null +++ b/src/main/java/com/inspect/nvr/service/LincseekCameraService.java @@ -0,0 +1,186 @@ +package com.inspect.nvr.service; + +import com.inspect.nvr.domain.Infrared.Camera; +import com.inspect.nvr.domain.Infrared.NvrInfo; +import com.inspect.nvr.domain.Infrared.TemperatureData; +import com.inspect.nvr.jna.lincseek.IRNetSDK; +import com.inspect.nvr.jna.lincseek.IRNetSDKCallback; +import com.inspect.nvr.jna.lincseek.IRNetSDKConst; +import com.inspect.nvr.jna.lincseek.IRNetSDKStruct; +import com.inspect.nvr.jna.lincseek.IRNetSDKStruct.IRNETHANDLE; +import com.sun.jna.Memory; +import com.sun.jna.Pointer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +@Service +public class LincseekCameraService extends CommonCameraService { + // [新增]全局流水号生成器 + private static final AtomicInteger SERIAL_COUNTER = new AtomicInteger(1); + // Key: CmdSerial (流水号), Value: CompletableFuture (用于通知调用线程) + private static final ConcurrentHashMap> PENDING_REQUESTS = new ConcurrentHashMap<>(); + + @Resource + private IRNetSDK irNetSDK; + @Resource + private LincseekLoginService lincseekLoginService; + + public static int nextSerial() { + return SERIAL_COUNTER.updateAndGet(current -> (current + 1) & 0xFFFF); + } + + public static Pointer stringToPointer(String str) { + if (str == null) return null; + byte[] bytes = str.getBytes(); // 1. 转换为字节数组 + Pointer pointer = new Memory(bytes.length + 1); // 2. 分配内存(+1 用于存放 \0) + pointer.write(0, bytes, 0, bytes.length); // 3. 写入字节 + pointer.setByte(bytes.length, (byte) 0); // 4. 追加空字节(Null-termination) + return pointer; + } + + /** + * 受并发控制的朗驰抓图 + */ + public byte[] capture(NvrInfo nvrInfo, int channel) { + return withConcurrencyControl(nvrInfo, channel, () -> captureWithRetry(nvrInfo, channel)); + } + + private byte[] captureWithRetry(NvrInfo nvrInfo, int channel) { + Path fullPath = getFullPath("lc", nvrInfo.getNvrIp(), channel); + ensureDirectoryExists(fullPath.getParent()); + int retryCount = 0; + int maxRetries = DEFAULT_MAX_RETRIES; + while (retryCount < maxRetries) { + try { + byte[] imageBytes = jpegCapSingle(nvrInfo, channel, fullPath); + log.info("[朗驰]抓图成功:第{}次,文件地址:{}", retryCount + 1, fullPath); + return imageBytes; + } catch (Exception e) { + log.error("[朗驰]抓图异常(第{}次):{}", retryCount + 1, e.getMessage()); + } finally { + retryCount++; + } + } + // 当所有抓图方式均失败时,记录失败图片 + writeCaptureFailedImage(fullPath); + log.error("[朗驰]抓图失败,图片地址:{}", fullPath); + return new byte[0]; + } + + private byte[] jpegCapSingle(NvrInfo nvrInfo, int channel, Path fullPath) { + IRNetSDKCallback.JpegDataCallback jpegCb = (hHandle, mCh, pBuffer, size, extraData, userdata) -> { + String requestKey = userdata.getString(0); + CompletableFuture future = PENDING_REQUESTS.remove(requestKey); + if (future != null) { + log.info("[朗驰]匹配到抓图回调 (requestKey={}, 通道={}, 大小={}B)", requestKey, mCh, size); + byte[] jpeg = pBuffer.getByteArray(0, size); + future.complete(jpeg); + } else { + // 可能是由于超时已经被移除了,或者是其他类型的抓图 + log.error("[朗驰]未匹配的抓图回调,requestKey={}", requestKey); + } + }; + + int mySerialId = nextSerial(); + String requestKey = ":" + mySerialId; + Pointer userData = stringToPointer(requestKey); + IRNETHANDLE capHandle = irNetSDK.IRNET_ClientJpegCapStart("video server", nvrInfo.getNvrIp(), nvrInfo.getAccount(), nvrInfo.getPassword(), (short) nvrInfo.getServerPort().intValue(), jpegCb, userData); + if (!IRNETHANDLE.INVALID_HANDLE_VALUE.equals(capHandle)) { + CompletableFuture future = new CompletableFuture<>(); + log.info("capHandle: {}, {}", capHandle.toString(), capHandle.hashCode()); + PENDING_REQUESTS.put(requestKey, future); + final int TIMEOUT_SEC = 10; + try { + boolean isCaptured = irNetSDK.IRNET_ClientJpegCapSingle(capHandle, channel, 100); + if (!isCaptured) { + throw new RuntimeException("SDK抓图失败"); + } + byte[] byteArray = future.get(TIMEOUT_SEC, TimeUnit.SECONDS); + Files.write(fullPath, byteArray); + return byteArray; + } catch (Exception e) { + throw new RuntimeException("[朗驰]抓图异常:", e); + } finally { + PENDING_REQUESTS.remove(requestKey); + irNetSDK.IRNET_ClientJpegCapStop(capHandle); + } + } + return null; + } + + public TemperatureData getTemp(Camera camera) { + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + + int channel = camera.getChannel(); + return withConcurrencyControl(nvrInfo, channel, () -> tempWithRetry(nvrInfo, channel)); + } + + /** + * 获取最高温、最低温、平均温 + */ + private TemperatureData tempWithRetry(NvrInfo nvrInfo, int channel) { + IRNETHANDLE msgHandle = irNetSDK.IRNET_ClientMessageOpen("video server", nvrInfo.getNvrIp(), nvrInfo.getAccount(), nvrInfo.getPassword(), (short) nvrInfo.getServerPort().intValue()); + try { + if (!IRNETHANDLE.INVALID_HANDLE_VALUE.equals(msgHandle)) { + IRNetSDKStruct.VSNET_TEMP_VALUE_EX temps = new IRNetSDKStruct.VSNET_TEMP_VALUE_EX(); + temps.write(); + int r = irNetSDK.IRNET_ClientMessageOpt(msgHandle, IRNetSDKConst.MessageOpt.MESSAGE_CMD_GET_TEMPVALUE_EX, channel, temps.getPointer(), null, null); + if (r == 1) { + temps.read(); + float maxTemp = temps.m_maxtempinfo.m_temp_value; + int maxX = temps.m_maxtempinfo.m_temp_x; + int maxY = temps.m_maxtempinfo.m_temp_y; + float minTemp = temps.m_mintempinfo.m_temp_value; + int minX = temps.m_mintempinfo.m_temp_x; + int minY = temps.m_mintempinfo.m_temp_y; + float avgTemp = temps.m_avgtempinfo; + log.info("[朗驰]测温结果: 最高={}℃({},{}), 最低={}℃({},{}), 平均={}℃", + maxTemp, maxX, maxY, minTemp, minX, minY, avgTemp); + return new TemperatureData( + String.valueOf(maxTemp), + String.valueOf(minTemp), + avgTemp, + 0, + channel, + -1 + ); + } + } + } catch (Exception e) { + log.error("[朗驰]测温异常:", e); + } finally { + irNetSDK.IRNET_ClientMessageClose(msgHandle); + } + return null; + } + + /** + * 跳转预置位 + */ + public boolean ptzPreset(Camera camera) { + //预置位跳转 + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + nvrInfo.setChannelNumber(camera.getChannel()); + IRNETHANDLE hHandle = lincseekLoginService.login(nvrInfo); + boolean ret = irNetSDK.IRNET_ClientPTZCtrl(hHandle, IRNetSDKConst.PTZ_GOTOPOINT, camera.getPointNum(), 0, null, 0); + log.info("[朗驰]跳转预置位{}, 结果: {}", camera.getPointNum(), ret); + return ret; + } +} diff --git a/src/main/java/com/inspect/nvr/service/LincseekLoginService.java b/src/main/java/com/inspect/nvr/service/LincseekLoginService.java new file mode 100644 index 0000000..fcd38ed --- /dev/null +++ b/src/main/java/com/inspect/nvr/service/LincseekLoginService.java @@ -0,0 +1,123 @@ +package com.inspect.nvr.service; + +import com.alibaba.fastjson.JSONObject; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalCause; +import com.inspect.nvr.domain.Infrared.NvrInfo; +import com.inspect.nvr.jna.lincseek.IRNetSDK; +import com.inspect.nvr.jna.lincseek.IRNetSDKStruct; +import com.inspect.nvr.jna.lincseek.IRNetSDKStruct.IRNETHANDLE; +import com.inspect.nvr.utils.redis.RedisService; +import com.sun.jna.Pointer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service +public class LincseekLoginService { + private static final String ERROR_LOGOUT_KEY = "lincseek:error"; + + @Resource + private RedisService redisService; + @Resource + private IRNetSDK irNetSDK; + + // 使用 Caffeine 缓存,10分钟未访问自动移除并登出 + private final Cache sessionCache = Caffeine.newBuilder() + // 10分钟未被get()就过期 + .expireAfterAccess(10, TimeUnit.MINUTES) + .removalListener((String ip, IRNETHANDLE handle, RemovalCause cause) -> { + if (handle != null && (cause == RemovalCause.EXPIRED || cause == RemovalCause.SIZE)) { + log.info("[朗驰]会话超时自动登出,ip: {},handler: {}", ip, handle); + doLogout(ip, handle); + } + }).build(); + + /** + * 登录(Caffeine.get 保证同一 IP 的并发请求只执行一次登录) + */ + public IRNETHANDLE login(NvrInfo nvrInfo) { + String ip = nvrInfo.getNvrIp(); + Integer port = nvrInfo.getServerPort(); + if (port == null) { + throw new IllegalArgumentException("serverPort 不能为空"); + } + + return sessionCache.get(ip, key -> { + IRNetSDKStruct.CHANNEL_CLIENTINFO info = IRNetSDKStruct.CHANNEL_CLIENTINFO.createWithUrl( + "video server", nvrInfo.getAccount(), nvrInfo.getPassword(), + (byte) nvrInfo.getChannelNumber().intValue(), ip, null, null, 0, null, null); + IRNETHANDLE handle = irNetSDK.IRNET_ClientStart(ip, info, port.shortValue(), 0); + + if (IRNETHANDLE.INVALID_HANDLE_VALUE.equals(handle)) { + throw new RuntimeException("[朗驰]登录失败, ip: " + ip); + } + + log.info("[朗驰]登录成功,ip:{},handler:{}", ip, handle); + return handle; + }); + } + + /** + * 记录注销失败信息到 Redis + */ + private void recordLogoutError(String ip, Integer userID, int errorCode) { + JSONObject json = new JSONObject(); + json.put("ip", ip); + json.put("userID", userID); + json.put("errorCode", errorCode); + json.put("time", System.currentTimeMillis()); + redisService.redisTemplate.opsForZSet().add(ERROR_LOGOUT_KEY, json.toJSONString(), System.currentTimeMillis()); + } + + /** + * 登出具体实现 + */ + public void doLogout(String ip, IRNETHANDLE handle) { + if (handle != null) { + // 调用登出SDK + boolean isLogout = irNetSDK.IRNET_ClientStop(handle); + if (isLogout) { + log.info("[朗驰]登出成功,ip: {},handle: {}", ip, handle); + } else { + log.error("[朗驰]登出失败,ip: {},handle: {}", ip, handle); + // 登出失败日志记录到Redis中 + recordLogoutError(ip, (int) Pointer.nativeValue(handle), -1); + } + } + } + + /** + * 登出 + */ + public synchronized void logout(String ip) { + IRNETHANDLE handle = sessionCache.getIfPresent(ip); + if (handle != null) { + sessionCache.invalidate(ip); + } + } + + /** + * 登出所有用户 + */ + public void logoutAll() { + // 获取所有缓存的IP和userID + sessionCache.asMap().forEach((ip, handle) -> { + doLogout(ip, handle); + }); + // 清空整个缓存 + sessionCache.invalidateAll(); + log.info("[朗驰]所有用户已登出"); + } + + /** + * 检查是否已登录(同时刷新过期时间) + */ + public boolean isLoggedIn(String ip) { + return sessionCache.getIfPresent(ip) != null; + } +} diff --git a/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java b/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java index 19c26ee..6131e06 100644 --- a/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java +++ b/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java @@ -61,6 +61,8 @@ public class IvsCameraServiceImpl implements IvsCameraService { private DahuaCameraService dahuaCameraService; @Autowired private HikLoginService hikLoginService; + @Resource + private LincseekCameraService lincseekCameraService; @Override public IvsPresetListView ptzPresetList(String cameraCode, String domainCode) { @@ -88,7 +90,7 @@ public class IvsCameraServiceImpl implements IvsCameraService { Camera camera = new Camera(); String[] splitArray = param.getAddress().split(":"); //给camera赋值 - //cameraType=0海康 1大华 + //cameraType=0海康 1大华 2朗驰 String ip = splitArray[0]; int port = Integer.parseInt(splitArray[1]); int channel = Integer.parseInt(splitArray[2]); @@ -139,9 +141,12 @@ public class IvsCameraServiceImpl implements IvsCameraService { public PtzControlResult ptzDetailControl(Camera camera, int cameraType) { //大华预置位跳转 PtzControlResult ptzControlResult = null; - if (ObjectUtil.equals(cameraType, 1)) { +// if (ObjectUtil.equals(cameraType, 1)) { + if (CameraEnum.DAHUA.getCode() == cameraType) { log.info("开始登录大华NVR 进行跳转预置位"); dahuaService.cameraControl(camera, 0, 0, 0); + } else if (CameraEnum.LINCSEEK.getCode() == cameraType) { + lincseekCameraService.ptzPreset(camera); } else { //海康预置位跳转 NvrInfo nvrInfo = new NvrInfo(); @@ -401,6 +406,10 @@ public class IvsCameraServiceImpl implements IvsCameraService { log.info("大华相机抓图"); byte[] bytes = dahuaCameraService.capture(nvrInfo, camera.getChannel()); return new ByteArrayInputStream(bytes); + } else if (CameraEnum.LINCSEEK.getCode() == camera.getCameraType()) { + log.info("朗驰相机抓图"); + byte[] bytes = lincseekCameraService.capture(nvrInfo, camera.getChannel()); + return new ByteArrayInputStream(bytes); } else { log.info("海康相机抓图"); byte[] bytes = hikCameraService.capture(nvrInfo, camera.getChannel()); diff --git a/src/main/java/com/inspect/nvr/task/ImageCleanupTask.java b/src/main/java/com/inspect/nvr/task/ImageCleanupTask.java new file mode 100644 index 0000000..9ba83f4 --- /dev/null +++ b/src/main/java/com/inspect/nvr/task/ImageCleanupTask.java @@ -0,0 +1,101 @@ +package com.inspect.nvr.task; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.time.format.DateTimeParseException; +import java.util.Comparator; +import java.util.stream.Stream; + +import static com.inspect.nvr.service.CommonCameraService.FILE_DIR; + +/** + * 定期清理抓拍图片 + */ +@Component +@Slf4j +public class ImageCleanupTask { + // 图片保留时长 + private static final int RETENTION_DAYS = 7; + + @PostConstruct + public void init() { + cleanupOldFolders(); + } + + + @Scheduled(cron = "0 0 22 * * SUN") + public void cleanupOldFolders() { + log.info("开始执行图片文件夹清理任务..."); + + try { + String basePath = FILE_DIR; + Path rootPath = Paths.get(basePath); + if (!Files.exists(rootPath)) { + log.warn("基础目录不存在: {}", basePath); + return; + } + + LocalDate today = LocalDate.now(); + LocalDate thresholdDate = today.minusDays(RETENTION_DAYS); + + try (Stream paths = Files.list(rootPath)) { + paths.filter(Files::isDirectory) + .forEach(dir -> { + String dirName = dir.getFileName().toString(); + if (isDateFolder(dirName)) { + try { + LocalDate folderDate = LocalDate.parse(dirName); + if (folderDate.isBefore(thresholdDate)) { + deleteDirectoryRecursively(dir); + log.info("已删除过期文件夹: {} (日期: {})", dirName, folderDate); + } + } catch (DateTimeParseException e) { + log.debug("文件夹名称不是有效日期格式: {}", dirName); + } catch (Exception e) { + log.error("处理文件夹 {} 时出错", dirName, e); + } + } + }); + } + + log.info("图片清理任务执行完成"); + } catch (Exception e) { + log.error("清理任务执行失败", e); + } + } + + /** + * 判断文件夹名是否为 YYYY-MM-dd 格式 + */ + private boolean isDateFolder(String name) { + return name.matches("\\d{4}-\\d{2}-\\d{2}"); + } + + /** + * 递归删除目录及其所有内容 + */ + private void deleteDirectoryRecursively(Path directory) throws IOException { + if (!Files.exists(directory)) { + return; + } + + try (Stream walk = Files.walk(directory)) { + walk.sorted(Comparator.reverseOrder()) + .forEach(path -> { + try { + Files.delete(path); + } catch (IOException e) { + log.warn("删除文件/目录失败: {}", path, e); + } + }); + } + } +} diff --git a/src/main/java/com/inspect/nvr/utils/StringHexConverter.java b/src/main/java/com/inspect/nvr/utils/StringHexConverter.java index 634b655..071650a 100644 --- a/src/main/java/com/inspect/nvr/utils/StringHexConverter.java +++ b/src/main/java/com/inspect/nvr/utils/StringHexConverter.java @@ -30,6 +30,7 @@ public class StringHexConverter { // final String rawString = "3139322e3136382e312e3233313a383030303a31313a3231303a61646d696e3a323031362e682e4244"; // final String hex = fromHex(rawString); // log.info(hex); + // 0:NVRip 1:NVR端口 2:NVR通道 3:预置点位 4:摄像头品牌 5:NVR用户名 6:NVR密码 7:摄像头ip 8:摄像头端口 9:摄像头通道 10:摄像头用户名 11:摄像头密码 String rawString = "192.168.3.12:37777:2:2:1:admin:admin123:192.168.3.70:37777:2:admin:admin123"; byte[] bytes = rawString.getBytes(StandardCharsets.UTF_8); StringBuilder hex = new StringBuilder();