diff --git a/.gitignore b/.gitignore index f190b494..31d4ed38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ HELP.md +AGENTS.md target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ @@ -30,6 +31,8 @@ build/ !**/src/test/**/build/ /logs/ +/captures/ +/sdkLog/ ### VS Code ### .vscode/ diff --git a/src/main/java/com/inspect/nvr/config/HikLibConfig.java b/src/main/java/com/inspect/nvr/config/HikLibConfig.java index 1de7ca84..8c8d9ac3 100644 --- a/src/main/java/com/inspect/nvr/config/HikLibConfig.java +++ b/src/main/java/com/inspect/nvr/config/HikLibConfig.java @@ -41,11 +41,25 @@ public class HikLibConfig { //linux系统建议调用以下接口加载组件库 if (osSelect.isLinux()) { + //Linux系统加载库路径 + String arch = System.getProperty("os.arch").toLowerCase(); + System.out.println("OS:" + arch); + String strPath1, strPath2, strPathCom; + if (arch.contains("amd64") || arch.contains("x86_64") || arch.equals("x86") || arch.startsWith("i386") || arch.startsWith("i686")) { + strPath1 = System.getProperty("user.dir") + "/lib/hik-linux64/libcrypto.so.3"; + strPath2 = System.getProperty("user.dir") + "/lib/hik-linux64/libssl.so.3"; + strPathCom = System.getProperty("user.dir") + "/lib/hik-linux64/"; + System.out.println("x86 / x86_64 架构"); +// } else if (arch.contains("aarch64") || arch.contains("arm64") || arch.startsWith("arm")) { + } else { + strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1"; + strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1"; + strPathCom = System.getProperty("user.dir") + "/lib/"; + System.out.println("ARM / AArch64 架构"); + } + HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256); HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256); - //这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限 - String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1"; - String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1"; System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length()); ptrByteArray1.write(); @@ -55,7 +69,6 @@ public class HikLibConfig { ptrByteArray2.write(); hcNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer()); - String strPathCom = System.getProperty("user.dir") + "/lib/"; HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH(); System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length()); struComPath.write(); @@ -66,8 +79,7 @@ public class HikLibConfig { boolean initSuc = hcNetSDK.NET_DVR_Init(); //异常消息回调 - if(fExceptionCallBack == null) - { + if (fExceptionCallBack == null) { fExceptionCallBack = new HikFExceptionCallBack_Imp(); } @@ -80,8 +92,8 @@ public class HikLibConfig { //启动SDK写日志 hcNetSDK.NET_DVR_SetLogToFile(3, "./sdkLog", false); //设置连接时间与重连时间 - hcNetSDK.NET_DVR_SetConnectTime(200000,1); - hcNetSDK.NET_DVR_SetReconnect(100000,true); + hcNetSDK.NET_DVR_SetConnectTime(200000, 1); + hcNetSDK.NET_DVR_SetReconnect(100000, true); //连接所有nvr @@ -97,16 +109,25 @@ public class HikLibConfig { */ private boolean createSDKInstance() { if (hcNetSDK == null) { + String arch = System.getProperty("os.arch").toLowerCase(); + System.out.println("OS:" + arch); + synchronized (HCNetSDK.class) { String strDllPath = ""; try { if (osSelect.isWindows()) //win系统加载库路径 strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll"; - - else if (osSelect.isLinux()) + else if (osSelect.isLinux()) { //Linux系统加载库路径 - strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so"; + if (arch.contains("amd64") || arch.contains("x86_64") || arch.equals("x86") || arch.startsWith("i386") || arch.startsWith("i686")) { + strDllPath = System.getProperty("user.dir") + "/lib/hik-linux64/libhcnetsdk.so"; + System.out.println("x86 / x86_64 架构"); + } else if (arch.contains("aarch64") || arch.contains("arm64") || arch.startsWith("arm")) { + strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so"; + System.out.println("ARM / AArch64 架构"); + } + } hcNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class); // HCNetSDK INSTANCE = (HCNetSDK) Native.load(LibraryLoad.getLoadLibrary("libhcnetsdk"), HCNetSDK.class); } catch (Exception ex) { diff --git a/src/main/java/com/inspect/nvr/config/LincseekConfig.java b/src/main/java/com/inspect/nvr/config/LincseekConfig.java index 8542ebee..618f6b97 100644 --- a/src/main/java/com/inspect/nvr/config/LincseekConfig.java +++ b/src/main/java/com/inspect/nvr/config/LincseekConfig.java @@ -2,14 +2,7 @@ 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.*; import com.sun.jna.win32.W32APIFunctionMapper; import com.sun.jna.win32.W32APITypeMapper; import lombok.extern.slf4j.Slf4j; @@ -17,6 +10,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; +import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; @@ -30,6 +24,12 @@ public class LincseekConfig { @Bean public IRNetSDK initSDK() { + // 项目只有朗驰 Windows DLL,Linux 容器不加载它,避免影响海康和大华功能启动。 + if (!Platform.isWindows()) { + log.warn("[朗驰]当前系统非 Windows,已跳过仅支持 Windows 的朗驰 SDK 初始化"); + return createUnsupportedSdk(); + } + // 自定义 TypeMapper:将 native Pointer 转换为 IRNETHANDLE DefaultTypeMapper mergedMapper = new DefaultTypeMapper() { @Override @@ -74,4 +74,23 @@ public class LincseekConfig { return irNetSDK; } + /** + * 为不支持朗驰 DLL 的系统创建占位 Bean,让其他厂商功能正常启动。 + * + * @return 清理调用可安全返回,其他业务调用会抛出明确异常的 SDK 代理 + */ + private IRNetSDK createUnsupportedSdk() { + // 使用 JDK 代理保持既有依赖注入结构,不为单一平台限制改造多个业务服务。 + return (IRNetSDK) Proxy.newProxyInstance( + IRNetSDK.class.getClassLoader(), + new Class[]{IRNetSDK.class}, + (proxy, method, args) -> { + // 应用退出时没有实际朗驰资源,按清理成功返回,避免干扰其他 SDK 释放。 + if ("IRNET_ClientCleanup".equals(method.getName())) { + return true; + } + // 真正调用朗驰功能时直接说明平台限制,不伪造 SDK 结果。 + throw new UnsupportedOperationException("朗驰 SDK 仅支持 Windows,当前运行环境无法调用"); + }); + } }