1. 将sdk动态链接库dll集成到项目内,提升部署便捷性;
2. 增加设备断线重连回调方法,打印相关日志;
3. 删除多余依赖,减小jar包体积;
4. 处理SDK日志打印;
已添加1个文件
已重命名44个文件
已修改34个文件
已删除122个文件
已复制1个文件
136407 ■■■■■ 文件已修改
ard-work/pom.xml 397 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/cmd/startup.java 346 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java 736 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java 200 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java 1356 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/LibraryLoad.java 385 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/NetSDKLib.java 74661 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/Utils.java 420 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/CFG_MOTION_INFO.java 250 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_ALARM_DEVICE_MODIFIED_INFO.java 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO.java 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_IN_PERSON_INFO_INPUT_RESULT.java 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_IN_START_REDIRECT_SERVICE.java 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/UNPACKING_CHECK_INFO.java 176 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/CANDIDATE_INFO_CEX.java 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/DEV_EVENT_CROSSLINE_INFO.java 316 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/DEV_EVENT_CROSSREGION_INFO.java 418 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/EVENT_INTELLI_COMM_INFO.java 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/MEDIAFILE_FACERECOGNITION_INFO.java 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/CapturePictureModule.java 214 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/ConfigModule.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/LoginModule.java 289 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/RealPlayModule.java 204 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/service/IDhClientService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/dhsdk/service/impl/DhClientServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/common/GlobalVariable.java 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/sdk/ExceptionCallBack.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/sdk/HCNetSDK.java 21398 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/IHikClientService.java 226 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/dynamic-lib-load.xml 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/AudioRender.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/GdiPlus.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCCore.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDK.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/AnalyzeData.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/AudioIntercom.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/AudioRender.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCAlarm.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCAlarm.lib 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCCoreDevCfg.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCDisplay.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCGeneralCfgMgr.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCGeneralCfgMgr.lib 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCIndustry.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCPlayBack.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCPreview.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCPreview.lib 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCVoiceTalk.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/OpenAL32.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/StreamTransClient.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/SystemTransform.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HCNetSDKCom/libiconv2.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HXVA.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/HmMerge.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/ImageAlg.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/Infra.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/IvsDrawer.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/MP_Render.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/NPQos.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/OpenAL32.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/PlayCtrl.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/RenderEngine.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/StreamConvertor.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/SuperRender.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/YUVProcess.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/avnetsdk.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/dhconfigsdk.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/dhnetsdk.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/dhplay.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/hlog.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/hpr.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/libcrypto-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/libmmd.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/libssl-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/lib/win64/zlib1.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/ClientDemoDll/ReadMe.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/ClientDemoDll/calib.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/ClientDemoDll/iconv.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/ClientDemoDll/libcrypto-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/ClientDemoDll/libssl-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/ClientDemoDll/libxml2.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/ClientDemoDll/zlib1.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hikDll/OpenAL32.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/mediamtx/LICENSE 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/mediamtx/ffmpeg.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/mediamtx/mediamtx.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/mediamtx/mediamtx.yml 556 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/minio/minio.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/EventLog.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/Redis on Windows Release Notes.docx 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/Redis on Windows.docx 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/Windows Service Documentation.docx 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/dump.rdb 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-benchmark.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-benchmark.pdb 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-check-aof.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-check-aof.pdb 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-cli.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-cli.pdb 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-desktop-manager-0.9.3.817.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-server.exe 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis-server.pdb 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis.windows-service.conf 1048 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/redis/redis.windows.conf 1048 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/Procfile 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/config.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/Bunny.html 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/LICENSE 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/README.md 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/admin.html 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/apprtc.html 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/apprtc.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/help.html 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/htmlmapmarker.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/index.html 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/info.png 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/janusconfig.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/janustest.html 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/janusvideoroom-element.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/janusvideoroom.html 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/janusvideoroom.js 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jitsi.ico 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jitsiroom.html 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jitsitest.html 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/JanusVideoRoom.html 723 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/WebRtcStreamer.html 520 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/XMPPVideoRoom.html 651 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Bold-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Bold-webfont.svg 1830 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Bold-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-BoldItalic-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-BoldItalic-webfont.svg 1830 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-BoldItalic-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Italic-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Italic-webfont.svg 1830 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Italic-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Light-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Light-webfont.svg 1831 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Light-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-LightItalic-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-LightItalic-webfont.svg 1835 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-LightItalic-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Regular-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Regular-webfont.svg 1831 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/fonts/OpenSans-Regular-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/index.html 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/janusvideoroom.js.html 422 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/scripts/linenumber.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/scripts/prettify/Apache-License-2.0.txt 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/scripts/prettify/lang-css.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/scripts/prettify/prettify.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/styles/jsdoc-default.css 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/styles/prettify-jsdoc.css 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/styles/prettify-tomorrow.css 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/webrtcstreamer.js.html 334 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/jsdoc/xmppvideoroom.js.html 417 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/EventEmitter.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/adapter.min.js 3514 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/ag-grid.min.js 836 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/blazeface 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/body-pix 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/coco-ssd 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/deeplab 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/jquery-3.5.1.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/lib-jitsi-meet.min.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/posenet 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/strophe.disco.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/strophe.jingle.sdp.js 782 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/strophe.min.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/strophe.muc.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/tf-backend-wasm.js 5796 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/tfjs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/tfjs-backend-wasm-simd.wasm 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/tfjs-backend-wasm.wasm 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/libs/whep-video.component.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/map.html 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/nav.css 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/sendstream.html 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/styles.css 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/tensorflow.js 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer-algo-element.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer-element.html 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer-element.js 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer-footer-element.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer-menu-element.js 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer-options-element.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer-selector-element.js 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc-streamer.html 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtc.png 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtcconfig.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtcstreamer.html 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/webrtcstreamer.js 305 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/whep.html 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/xmppconfig.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/xmppvideoroom.html 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/html/xmppvideoroom.js 442 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/webrtc/webrtc-streamer.exe 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 512 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-dev.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/logback.xml 650 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/pom.xml
@@ -1,203 +1,196 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.8.5</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ard-work</artifactId>
    <description>
        安瑞达业务模块
    </description>
    <dependencies>
        <dependency>
            <groupId>net.sf.ucanaccess</groupId>
            <artifactId>ucanaccess</artifactId>
            <version>5.0.1</version>
        </dependency>
        <!-- 通用工具-->
        <!--        <dependency>-->
        <!--            <groupId>commons-codec</groupId>-->
        <!--            <artifactId>commons-codec</artifactId>-->
        <!--            <version>1.10</version>-->
        <!--        </dependency>-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
        </dependency>
        <!--大华二次开发依赖jar包-->
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.4.0</version>
        </dependency>
        <!--海康录像机二次开发依赖jar包-->
        <dependency>
            <groupId>net.java.jna</groupId>
            <artifactId>jna</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>net.java.examples</groupId>
            <artifactId>examples</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--thymeleaf 模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.3.5</version>
        </dependency>
        <!--mqtt-->
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
            <version>6.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-system</artifactId>
        </dependency>
        <!--knife4j依赖-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
        <!--张建提供引导依赖-->
        <dependency>
            <groupId>org.gavaghan</groupId>
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.7</version>
        </dependency>
        <!-- Forest -->
        <dependency>
            <groupId>com.dtflys.forest</groupId>
            <artifactId>forest-spring-boot-starter</artifactId>
            <version>1.5.33</version>
        </dependency>
        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.36</version>
        </dependency>
        <!--三一车辆依赖-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.14</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.35</version>
        </dependency>
        <dependency>
            <groupId>com.sy</groupId>
            <artifactId>gps-push-client</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>2.11.2</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.63.Final</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-annotations</artifactId>
            <version>3.0.3</version>
            <scope>compile</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.axis/axis -->
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.xml.rpc/javax.xml.rpc-api -->
        <dependency>
            <groupId>javax.xml.rpc</groupId>
            <artifactId>javax.xml.rpc-api</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.6.3</version>
        </dependency>
        <dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.5</version>
        </dependency>
    </dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.8.5</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ard-work</artifactId>
    <description>
        安瑞达业务模块
    </description>
    <dependencies>
        <dependency>
            <groupId>net.sf.ucanaccess</groupId>
            <artifactId>ucanaccess</artifactId>
            <version>5.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
        </dependency>
        <!--大华二次开发依赖jar包-->
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.4.0</version>
        </dependency>
        <!--海康录像机二次开发依赖jar包-->
        <dependency>
            <groupId>net.java.jna</groupId>
            <artifactId>jna</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>net.java.examples</groupId>
            <artifactId>examples</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--thymeleaf 模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.3.5</version>
        </dependency>
        <!--mqtt-->
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
            <version>6.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-system</artifactId>
        </dependency>
        <!--knife4j依赖-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
        <!--张建提供引导依赖-->
        <dependency>
            <groupId>org.gavaghan</groupId>
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.bytedeco</groupId>-->
<!--            <artifactId>javacv-platform</artifactId>-->
<!--            <version>1.5.7</version>-->
<!--        </dependency>-->
        <!-- Forest -->
        <dependency>
            <groupId>com.dtflys.forest</groupId>
            <artifactId>forest-spring-boot-starter</artifactId>
            <version>1.5.33</version>
        </dependency>
        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.36</version>
        </dependency>
        <!--三一车辆依赖-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.14</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.35</version>
        </dependency>
        <dependency>
            <groupId>com.sy</groupId>
            <artifactId>gps-push-client</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>2.11.2</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.63.Final</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-annotations</artifactId>
            <version>3.0.3</version>
            <scope>compile</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.axis/axis -->
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.xml.rpc/javax.xml.rpc-api -->
        <dependency>
            <groupId>javax.xml.rpc</groupId>
            <artifactId>javax.xml.rpc-api</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.6.3</version>
        </dependency>
        <dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.5</version>
        </dependency>
    </dependencies>
</project>
ard-work/src/main/java/com/ruoyi/cmd/startup.java
@@ -1,171 +1,177 @@
package com.ruoyi.cmd;
import com.ruoyi.utils.process.CmdUtils;
import com.sun.jna.Platform;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Description: 外部程序启动
 * @ClassName: startup
 * @Author: 刘苏义
 * @Date: 2023年09月22日9:56:57
 **/
@Slf4j(topic = "cmd")
@Component
public class startup implements ApplicationContextInitializer {
    //minio
    String minioName = "minio.exe";
    @Value("${minio.accessKey}")
    String accessKey;
    @Value("${minio.secretKey}")
    String secretKey;
    @Value("${minio.path}")
    String path;
    @Value("${minio.enabled}")
    Boolean minioEnabled;
    //mediamtx
    String mediamtxName = "mediamtx.exe";
    @Value("${mediamtx.enabled}")
    Boolean mediamtxEnabled;
    //webrtc-streamer
    String webrtcName = "webrtc-streamer.exe";
    @Value("${webrtc.host}")
    String webrtcHost;
    @Value("${webrtc.enabled}")
    Boolean webrtcEnabled;
    //redis
    String redisName = "redis-server.exe";
    /**
     * 程序初始化启动redis
     * 刘苏义
     * 2023/9/22 10:38:41
     */
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        if (Platform.isWindows()) {
            String exePath = System.getProperty("user.dir") + File.separator + "lib" + File.separator + "redis" + File.separator + redisName;
            List<String> cmd = new ArrayList<>();
            cmd.add(exePath);
            if (CmdUtils.isProcessRunning(redisName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(redisName);
            }
            // 启动后台进程
            CmdUtils.commandStart(redisName, cmd, null);
            // 启动cmd窗口
//                String[] command = {"cmd", "/c", "start", exePath, "-H127.0.0.1:8000", "-o"};
//                CmdUtils.commandStart(command);
        }
    }
    @PostConstruct
    public void init() {
        if (minioEnabled) {
            log.info("初始化启动minio");
            if (Platform.isWindows()) {
                String exePath = System.getProperty("user.dir") + File.separator + "lib" + File.separator + "minio" + File.separator + minioName;
                Map<String, String> env = new HashMap<>();
                env.put("MINIO_ROOT_USER", accessKey);
                env.put("MINIO_ROOT_PASSWORD", secretKey);
                List<String> cmd = new ArrayList<>();
                cmd.add(exePath);
                cmd.add("server");
                cmd.add(path);
                cmd.add("--console-address=0.0.0.0:9000");
                cmd.add("--address=0.0.0.0:9001");
                if (CmdUtils.isProcessRunning(minioName)) {
                    // 进程已经在运行,结束该进程
                    CmdUtils.stopProcess(minioName);
                }
                // 启动后台进程
                CmdUtils.commandStart(minioName, cmd, env);
                // 启动cmd窗口
                //String[] command = {"cmd", "/c", "start", exePath};
                //CmdUtils.commandStart(command);
            }
        }
        if (mediamtxEnabled) {
            log.info("初始化启动mediaMTX");
            if (Platform.isWindows()) {
                String exePath = System.getProperty("user.dir") + File.separator + "lib" + File.separator + "mediamtx" + File.separator + mediamtxName;
                String ymlPath = System.getProperty("user.dir") + File.separator + "lib" + File.separator + "mediamtx" + File.separator + "mediamtx.yml";
                List<String> cmd = new ArrayList<>();
                cmd.add(exePath);
                cmd.add(ymlPath);
                if (CmdUtils.isProcessRunning(mediamtxName)) {
                    // 进程已经在运行,结束该进程
                    CmdUtils.stopProcess(mediamtxName);
                }
                // 启动后台进程
                CmdUtils.commandStart(mediamtxName, cmd, null);
                // 启动cmd窗口
//            String[] command = {"cmd","/c","start",exePath,ymlPath};
//            CmdUtils.commandStart(command);
            }
        }
        if (webrtcEnabled) {
            log.info("初始化启动webrtc-streamer");
            if (Platform.isWindows()) {
                String exePath = System.getProperty("user.dir") + File.separator + "lib" + File.separator + "webrtc" + File.separator + webrtcName;
                List<String> cmd = new ArrayList<>();
                cmd.add(exePath);
                cmd.add("-H" + webrtcHost);
                cmd.add("-o");
                if (CmdUtils.isProcessRunning(webrtcName)) {
                    // 进程已经在运行,结束该进程
                    CmdUtils.stopProcess(webrtcName);
                }
                // 启动后台进程
                CmdUtils.commandStart(webrtcName, cmd, null);
                // 启动cmd窗口
//                String[] command = {"cmd", "/c", "start", exePath, "-H127.0.0.1:8000", "-o"};
//                CmdUtils.commandStart(command);
            }
        }
    }
    @PreDestroy
    public void destroy() {
        if (minioEnabled) {
            log.info("销毁minio");
            if (CmdUtils.isProcessRunning(minioName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(minioName);
            }
        }
        if (mediamtxEnabled) {
            log.info("销毁mediaMtx");
            if (CmdUtils.isProcessRunning(mediamtxName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(mediamtxName);
            }
        }
        if (webrtcEnabled) {
            log.info("销毁webrtc-streamer");
            if (CmdUtils.isProcessRunning(webrtcName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(webrtcName);
            }
        }
        if (true) {
            log.info("销毁redis");
            if (CmdUtils.isProcessRunning(redisName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(redisName);
            }
        }
    }
package com.ruoyi.cmd;
import com.ruoyi.utils.process.CmdUtils;
import com.sun.jna.Platform;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Description: 外部程序启动
 * @ClassName: startup
 * @Author: 刘苏义
 * @Date: 2023年09月22日9:56:57
 **/
@Slf4j(topic = "cmd")
@Component
public class startup implements ApplicationContextInitializer {
    //minio
    String minioName = "minio.exe";
    @Value("${minio.accessKey}")
    String accessKey;
    @Value("${minio.secretKey}")
    String secretKey;
    @Value("${minio.path}")
    String path;
    @Value("${minio.enabled}")
    Boolean minioEnabled;
    //mediamtx
    String mediamtxName = "mediamtx.exe";
    @Value("${mediamtx.enabled}")
    Boolean mediamtxEnabled;
    //webrtc-streamer
    String webrtcName = "webrtc-streamer.exe";
    @Value("${webrtc.host}")
    String webrtcHost;
    @Value("${webrtc.enabled}")
    Boolean webrtcEnabled;
    //redis
    String redisName = "redis-server.exe";
    /**
     * 程序初始化启动redis
     * 刘苏义
     * 2023/9/22 10:38:41
     */
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        if (Platform.isWindows()) {
            String exePath = System.getProperty("user.dir") + File.separator + "server" + File.separator + "redis" + File.separator + redisName;
            List<String> cmd = new ArrayList<>();
            cmd.add(exePath);
            if (CmdUtils.isProcessRunning(redisName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(redisName);
            }
            // 启动后台进程
            CmdUtils.commandStart(redisName, cmd, null);
            // 启动cmd窗口
            //String[] command = {"cmd", "/c", "start", exePath, "-H127.0.0.1:8000", "-o"};
            //CmdUtils.commandStart(command);
        }
    }
    @PostConstruct
    public void init() {
        if (minioEnabled) {
            log.info("初始化启动minio");
            if (Platform.isWindows()) {
                String exePath = System.getProperty("user.dir") + File.separator + "server" + File.separator + "minio" + File.separator + minioName;
                Map<String, String> env = new HashMap<>();
                env.put("MINIO_ROOT_USER", accessKey);
                env.put("MINIO_ROOT_PASSWORD", secretKey);
                List<String> cmd = new ArrayList<>();
                cmd.add(exePath);
                cmd.add("server");
                cmd.add(path);
                cmd.add("--console-address=0.0.0.0:9000");
                cmd.add("--address=0.0.0.0:9001");
                if (CmdUtils.isProcessRunning(minioName)) {
                    // 进程已经在运行,结束该进程
                    CmdUtils.stopProcess(minioName);
                }
                // 启动后台进程
                CmdUtils.commandStart(minioName, cmd, env);
                // 启动cmd窗口
                //String[] command = {"cmd", "/c", "start", exePath};
                //CmdUtils.commandStart(command);
            }
        }
        if (mediamtxEnabled) {
            log.info("初始化启动mediaMTX");
            if (Platform.isWindows()) {
                String exePath = System.getProperty("user.dir") + File.separator + "server" + File.separator + "mediamtx" + File.separator + mediamtxName;
                String ymlPath = System.getProperty("user.dir") + File.separator + "server" + File.separator + "mediamtx" + File.separator + "mediamtx.yml";
                List<String> cmd = new ArrayList<>();
                cmd.add(exePath);
                cmd.add(ymlPath);
                if (CmdUtils.isProcessRunning(mediamtxName)) {
                    // 进程已经在运行,结束该进程
                    CmdUtils.stopProcess(mediamtxName);
                }
                // 启动后台进程
                CmdUtils.commandStart(mediamtxName, cmd, null);
                // 启动cmd窗口
//            String[] command = {"cmd","/c","start",exePath,ymlPath};
//            CmdUtils.commandStart(command);
            }
        }
        if (webrtcEnabled) {
            log.info("初始化启动webrtc-streamer");
            if (Platform.isWindows()) {
                String exePath = System.getProperty("user.dir") + File.separator + "server" + File.separator + "webrtc" + File.separator + webrtcName;
                List<String> cmd = new ArrayList<>();
                cmd.add(exePath);
                cmd.add("-H" + webrtcHost);
                cmd.add("-o");
                if (CmdUtils.isProcessRunning(webrtcName)) {
                    // 进程已经在运行,结束该进程
                    CmdUtils.stopProcess(webrtcName);
                }
                // 启动后台进程
                CmdUtils.commandStart(webrtcName, cmd, null);
                // 启动cmd窗口
//                String[] command = {"cmd", "/c", "start", exePath, "-H127.0.0.1:8000", "-o"};
//                CmdUtils.commandStart(command);
            }
        }
    }
    @PreDestroy
    public void destroy() {
        if (minioEnabled) {
            log.info("销毁minio");
            if (CmdUtils.isProcessRunning(minioName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(minioName);
            }
        }
        if (mediamtxEnabled) {
            log.info("销毁mediaMtx");
            if (CmdUtils.isProcessRunning(mediamtxName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(mediamtxName);
            }
        }
        if (webrtcEnabled) {
            log.info("销毁webrtc-streamer");
            if (CmdUtils.isProcessRunning(webrtcName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(webrtcName);
            }
        }
        if (true) {
            log.info("销毁redis");
            if (CmdUtils.isProcessRunning(redisName)) {
                // 进程已经在运行,结束该进程
                CmdUtils.stopProcess(redisName);
            }
        }
    }
}
ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java
@@ -1,371 +1,365 @@
package com.ruoyi.device.camera.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.camera.service.ICameraSdkService;
import com.ruoyi.device.dhsdk.service.IDhClientService;
import com.ruoyi.device.hiksdk.service.IHikClientService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.dhsdk.service.IDhClientService;
import com.ruoyi.device.hiksdk.service.IHikClientService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
 * @Description:
 * @ClassName: CameraSdkController
 * @Author: 刘苏义
 * @Date: 2023年10月14日17:02:56
 **/
@Api(tags = "相机通用SDK接口")
@Controller
@RequestMapping("/cameraSdk")
@Anonymous
public class CameraSdkController extends BaseController {
    @Resource
    private ICameraSdkService cameraSdkService;
    @Resource
    private IArdCamerasService ardCamerasService;
    /**
     * @描述 初始加载SDK库文件
     * @返回值 void
     * @创建人 刘苏义
     * @创建时间 2023/1/17 16:13
     * @修改人和其它信息 if (Platform.isLinux())
     */
    @PostConstruct
    public void initSDK() {
        cameraSdkService.initSDK();
    }
    @RequestMapping("/preview")
    private String preview() {
        return "preview";
    }
    @RequestMapping("/index")
    private String index() {
        return "test";
    }
    @GetMapping("/list")
    public @ResponseBody
    AjaxResult list(ArdCameras ardCamera) {
        List<ArdCameras> list = ardCamerasService.selectArdCamerasListNoDataScope(ardCamera);
        return AjaxResult.success("相机列表:", list);
    }
    @ApiOperation("获取码流压缩参数")
    @PostMapping("/getVideoCompressionCfg")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取码流压缩参数", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getVideoCompressionCfg(@RequestBody CameraCmd cmd) {
        return AjaxResult.success(cameraSdkService.getVideoCompressionCfg(cmd));
    }
    @ApiOperation("在线状态")
    @PostMapping("/state")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId"})
    @Log(title = "在线状态", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getOnlineState(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        boolean onLine = cameraSdkService.isOnLine(cmd);
        return AjaxResult.success(onLine);
    }
    @ApiOperation(value = "云台控制", notes = "Code:1-左上 2-上 3-右上 4-左 5-巡航 6-右 7-左下 8-下 9-右下 10-焦距变大 11-焦距变小\n" +
            "12-焦点前调 13-焦点后调 14-光圈扩大 15-光圈缩小 16-雨刷开启")
    @PostMapping("/PTZControlWithSpeed")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.speed", "cmd.enable", "cmd.code"})
    @Log(title = "云台控制", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult PTZControlWithSpeed(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.pTZControl(cmd));
    }
    @ApiOperation("调用预置点")
    @PostMapping("/gotoPreset")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.presetIndex"})
    @Log(title = "调用预置点", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult gotoPreset(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.gotoPreset(cmd));
    }
    @ApiOperation("设置预置点")
    @PostMapping("/setPreset")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.presetIndex"})
    @Log(title = "设置预置点", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setPreset(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setPreset(cmd));
    }
    @ApiOperation("获取聚焦值")
    @PostMapping("/getFocusPos")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取聚焦值", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getFocusPos(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        int focus = cameraSdkService.getFocusPos(cmd);
        return AjaxResult.success("获取聚焦值", focus);
    }
    @ApiOperation("设置聚焦值")
    @PostMapping("/setFocusPos")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.dwFocusPos"})
    @Log(title = "设置聚焦值", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setFocusPos(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setFocusPos(cmd));
    }
    @ApiOperation("获取PTZ")
    @PostMapping("/getPTZ")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取PTZ", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getPTZ(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        Map<String, Object> ptzMap = cameraSdkService.getPtz(cmd);
        return AjaxResult.success("获取ptz", ptzMap);
    }
    @ApiOperation("获取PTZ范围")
    @PostMapping("/getPTZScope")
    @Log(title = "获取PTZ范围", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult getPTZScope(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        Map<String, Object> ptzMap = cameraSdkService.getPtzScope(cmd);
        return AjaxResult.success("获取ptz范围", ptzMap);
    }
    @ApiOperation("设置PTZ")
    @PostMapping("/setPTZ")
    @Log(title = "设置PTZ", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.ptzMap"})
    public @ResponseBody
    AjaxResult setPTZ(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setPtz(cmd));
    }
    @ApiOperation("指向目标")
    @PostMapping("/setTargetPosition")
    @Log(title = "指向目标", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.targetPosition"})
    public @ResponseBody
    AjaxResult setTargetPosition(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.guideTargetPosition(cmd));
    }
    @ApiOperation("设置零方位角")
    @PostMapping("/setZeroPTZ")
    @Log(title = "设置零方位角", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult setZeroPTZ(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setZeroPtz(cmd));
    }
    @ApiOperation("设置锁定")
    @PostMapping("/setPTZLock")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.expired"})
    @Log(title = "设置锁定", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setPTZLock(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return AjaxResult.success(cameraSdkService.controlLock(cmd));
    }
    @ApiOperation("设置解锁")
    @PostMapping("/setPTZUnLock")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId"})
    @Log(title = "设置解锁", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setPTZUnLock(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return AjaxResult.success(cameraSdkService.controlUnLock(cmd));
    }
    @ApiOperation("获取云台锁定信息")
    @PostMapping("/getPTZLockInfo")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取云台锁定信息", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getPTZLockInfo(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        int byWorkMode = cameraSdkService.getPTZLockInfo(cmd);
        if (byWorkMode == 0) {
            return AjaxResult.success("云台锁定状态:解锁");
        } else if (byWorkMode == 1) {
            return AjaxResult.success("云台锁定状态:锁定");
        } else {
            return AjaxResult.error("云台锁定状态:失败");
        }
    }
    @ApiOperation("透雾开关")
    @PostMapping("/defogcfg")
    @Log(title = "透雾开关", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult defogcfg(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlDefogcfg(cmd));
    }
    @ApiOperation("红外开关")
    @PostMapping("/infrarecfg")
    @Log(title = "红外开关", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult infrarecfg(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlInfrarecfg(cmd));
    }
    @ApiOperation(value = "手动/自动聚焦", notes = "true手动flase自动")
    @PostMapping("/focusMode")
    @Log(title = "手动/自动聚焦", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult enableFocusMode(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlFocusMode(cmd));
    }
    @ApiOperation(value = "获取聚焦模式", notes = "1手动2自动")
    @PostMapping("/getFocusMode")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult getFocusMode(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String focusMode = cameraSdkService.getFocusMode(cmd);
        return AjaxResult.success(focusMode);
    }
    @ApiOperation("云台加热")
    @PostMapping("/heateRpwron")
    @Log(title = "云台加热", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult heateRpwron(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlPTHeateRpwron(cmd));
    }
    @ApiOperation("镜头加热")
    @PostMapping("/cameraDeicing")
    @Log(title = "镜头加热", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult cameraDeicing(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlCameraDeicing(cmd));
    }
    @ApiOperation("相机抓图")
    @PostMapping("/picCutCate")
    @Log(title = "相机抓图", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult picCutCate(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String path = cameraSdkService.picCutCate(cmd);
        return toAjaxString(path, "相机抓图");
    }
    @ApiOperation("获取相机架设参数")
    @PostMapping("/getGisInfo")
    @Log(title = "获取相机架设参数", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult getGisInfo(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return AjaxResult.success(cameraSdkService.getGisInfo(cmd));
    }
    @ApiOperation("录像")
    @PostMapping("/record")
    @Log(title = "手动录像开始", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult record(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String url = cameraSdkService.record(cmd);
        return AjaxResult.success(url);
    }
    @ApiOperation("手动录像开始")
    @PostMapping("/recordStart")
    @Log(title = "手动录像开始", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult recordStart(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        boolean b = cameraSdkService.recordStart(cmd);
        return toAjax(b);
    }
    @ApiOperation("手动录像停止")
    @PostMapping("/recordStop")
    @Log(title = "手动录像停止", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.recordBucketName", "cmd.recordObjectName"})
    public @ResponseBody
    AjaxResult recordStop(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String url = cameraSdkService.recordStopToMinio(cmd);
        return AjaxResult.success(url);
    }
}
package com.ruoyi.device.camera.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.camera.service.ICameraSdkService;
import com.ruoyi.device.dhsdk.service.IDhClientService;
import com.ruoyi.device.hiksdk.service.IHikClientService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.dhsdk.service.IDhClientService;
import com.ruoyi.device.hiksdk.service.IHikClientService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
 * @Description:
 * @ClassName: CameraSdkController
 * @Author: 刘苏义
 * @Date: 2023年10月14日17:02:56
 **/
@Api(tags = "相机通用SDK接口")
@Controller
@RequestMapping("/cameraSdk")
@Anonymous
public class CameraSdkController extends BaseController {
    @Resource
    private ICameraSdkService cameraSdkService;
    @Resource
    private IArdCamerasService ardCamerasService;
    //初始登录所有相机
    @PostConstruct
    public void initLoginAll() {
        cameraSdkService.loginAll();
    }
    @RequestMapping("/preview")
    private String preview() {
        return "preview";
    }
    @RequestMapping("/index")
    private String index() {
        return "test";
    }
    @GetMapping("/list")
    public @ResponseBody
    AjaxResult list(ArdCameras ardCamera) {
        List<ArdCameras> list = ardCamerasService.selectArdCamerasListNoDataScope(ardCamera);
        return AjaxResult.success("相机列表:", list);
    }
    @ApiOperation("获取码流压缩参数")
    @PostMapping("/getVideoCompressionCfg")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取码流压缩参数", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getVideoCompressionCfg(@RequestBody CameraCmd cmd) {
        return AjaxResult.success(cameraSdkService.getVideoCompressionCfg(cmd));
    }
    @ApiOperation("在线状态")
    @PostMapping("/state")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId"})
    @Log(title = "在线状态", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getOnlineState(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        boolean onLine = cameraSdkService.isOnLine(cmd);
        return AjaxResult.success(onLine);
    }
    @ApiOperation(value = "云台控制", notes = "Code:1-左上 2-上 3-右上 4-左 5-巡航 6-右 7-左下 8-下 9-右下 10-焦距变大 11-焦距变小\n" +
            "12-焦点前调 13-焦点后调 14-光圈扩大 15-光圈缩小 16-雨刷开启")
    @PostMapping("/PTZControlWithSpeed")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.speed", "cmd.enable", "cmd.code"})
    @Log(title = "云台控制", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult PTZControlWithSpeed(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.pTZControl(cmd));
    }
    @ApiOperation("调用预置点")
    @PostMapping("/gotoPreset")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.presetIndex"})
    @Log(title = "调用预置点", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult gotoPreset(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.gotoPreset(cmd));
    }
    @ApiOperation("设置预置点")
    @PostMapping("/setPreset")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.presetIndex"})
    @Log(title = "设置预置点", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setPreset(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setPreset(cmd));
    }
    @ApiOperation("获取聚焦值")
    @PostMapping("/getFocusPos")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取聚焦值", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getFocusPos(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        int focus = cameraSdkService.getFocusPos(cmd);
        return AjaxResult.success("获取聚焦值", focus);
    }
    @ApiOperation("设置聚焦值")
    @PostMapping("/setFocusPos")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.dwFocusPos"})
    @Log(title = "设置聚焦值", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setFocusPos(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setFocusPos(cmd));
    }
    @ApiOperation("获取PTZ")
    @PostMapping("/getPTZ")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取PTZ", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getPTZ(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        Map<String, Object> ptzMap = cameraSdkService.getPtz(cmd);
        return AjaxResult.success("获取ptz", ptzMap);
    }
    @ApiOperation("获取PTZ范围")
    @PostMapping("/getPTZScope")
    @Log(title = "获取PTZ范围", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult getPTZScope(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        Map<String, Object> ptzMap = cameraSdkService.getPtzScope(cmd);
        return AjaxResult.success("获取ptz范围", ptzMap);
    }
    @ApiOperation("设置PTZ")
    @PostMapping("/setPTZ")
    @Log(title = "设置PTZ", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.ptzMap"})
    public @ResponseBody
    AjaxResult setPTZ(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setPtz(cmd));
    }
    @ApiOperation("指向目标")
    @PostMapping("/setTargetPosition")
    @Log(title = "指向目标", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.targetPosition"})
    public @ResponseBody
    AjaxResult setTargetPosition(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.guideTargetPosition(cmd));
    }
    @ApiOperation("设置零方位角")
    @PostMapping("/setZeroPTZ")
    @Log(title = "设置零方位角", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult setZeroPTZ(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.setZeroPtz(cmd));
    }
    @ApiOperation("设置锁定")
    @PostMapping("/setPTZLock")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.expired"})
    @Log(title = "设置锁定", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setPTZLock(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return AjaxResult.success(cameraSdkService.controlLock(cmd));
    }
    @ApiOperation("设置解锁")
    @PostMapping("/setPTZUnLock")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId"})
    @Log(title = "设置解锁", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult setPTZUnLock(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return AjaxResult.success(cameraSdkService.controlUnLock(cmd));
    }
    @ApiOperation("获取云台锁定信息")
    @PostMapping("/getPTZLockInfo")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    @Log(title = "获取云台锁定信息", businessType = BusinessType.CONTROL)
    public @ResponseBody
    AjaxResult getPTZLockInfo(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        int byWorkMode = cameraSdkService.getPTZLockInfo(cmd);
        if (byWorkMode == 0) {
            return AjaxResult.success("云台锁定状态:解锁");
        } else if (byWorkMode == 1) {
            return AjaxResult.success("云台锁定状态:锁定");
        } else {
            return AjaxResult.error("云台锁定状态:失败");
        }
    }
    @ApiOperation("透雾开关")
    @PostMapping("/defogcfg")
    @Log(title = "透雾开关", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult defogcfg(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlDefogcfg(cmd));
    }
    @ApiOperation("红外开关")
    @PostMapping("/infrarecfg")
    @Log(title = "红外开关", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult infrarecfg(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlInfrarecfg(cmd));
    }
    @ApiOperation(value = "手动/自动聚焦", notes = "true手动flase自动")
    @PostMapping("/focusMode")
    @Log(title = "手动/自动聚焦", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult enableFocusMode(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlFocusMode(cmd));
    }
    @ApiOperation(value = "获取聚焦模式", notes = "1手动2自动")
    @PostMapping("/getFocusMode")
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult getFocusMode(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String focusMode = cameraSdkService.getFocusMode(cmd);
        return AjaxResult.success(focusMode);
    }
    @ApiOperation("云台加热")
    @PostMapping("/heateRpwron")
    @Log(title = "云台加热", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult heateRpwron(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlPTHeateRpwron(cmd));
    }
    @ApiOperation("镜头加热")
    @PostMapping("/cameraDeicing")
    @Log(title = "镜头加热", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult cameraDeicing(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return toAjax(cameraSdkService.controlCameraDeicing(cmd));
    }
    @ApiOperation("相机抓图")
    @PostMapping("/picCutCate")
    @Log(title = "相机抓图", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult picCutCate(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String path = cameraSdkService.picCutCate(cmd);
        return toAjaxString(path, "相机抓图");
    }
    @ApiOperation("获取相机架设参数")
    @PostMapping("/getGisInfo")
    @Log(title = "获取相机架设参数", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult getGisInfo(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        return AjaxResult.success(cameraSdkService.getGisInfo(cmd));
    }
    @ApiOperation("录像")
    @PostMapping("/record")
    @Log(title = "手动录像开始", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"})
    public @ResponseBody
    AjaxResult record(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String url = cameraSdkService.record(cmd);
        return AjaxResult.success(url);
    }
    @ApiOperation("手动录像开始")
    @PostMapping("/recordStart")
    @Log(title = "手动录像开始", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"})
    public @ResponseBody
    AjaxResult recordStart(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        boolean b = cameraSdkService.recordStart(cmd);
        return toAjax(b);
    }
    @ApiOperation("手动录像停止")
    @PostMapping("/recordStop")
    @Log(title = "手动录像停止", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.recordBucketName", "cmd.recordObjectName"})
    public @ResponseBody
    AjaxResult recordStop(@RequestBody CameraCmd cmd) {
        cmd.setOperator(SecurityUtils.getUserId());
        String url = cameraSdkService.recordStopToMinio(cmd);
        return AjaxResult.success(url);
    }
}
ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java
@@ -1,100 +1,100 @@
package com.ruoyi.device.camera.service;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import java.util.Map;
public interface ICameraSdkService {
    //sdk初始化
    void initSDK();
    //登录
    Boolean login(ArdCameras ardCamera);
    //注销
    boolean logout(String cameraId);
    //在线状态
    boolean isOnLine(CameraCmd cmd);
    //云台控制
    boolean pTZControl(CameraCmd cmd);
    //设置聚焦值
    boolean setFocusPos(CameraCmd cmd);
    //获取聚焦值
    int getFocusPos(CameraCmd cmd);
    //设置预置位
    boolean setPreset(CameraCmd cmd);
    //调用预置位
    boolean gotoPreset(CameraCmd cmd);
    //获取码流压缩参数
    Map<String, Object> getVideoCompressionCfg(CameraCmd cmd);
    //透雾
    boolean controlDefogcfg(CameraCmd cmd);
    //红外
    boolean controlInfrarecfg(CameraCmd cmd);
    //聚焦模式
    boolean controlFocusMode(CameraCmd cmd);
    //获取聚焦模式
    String getFocusMode(CameraCmd cmd);
    //云台加热
    boolean controlPTHeateRpwron(CameraCmd cmd);
    //镜头加热除冰
    boolean controlCameraDeicing(CameraCmd cmd);
    //配置锁定
    boolean controlLock(CameraCmd cmd);
    //配置解锁
    boolean controlUnLock(CameraCmd cmd);
    //获取云台锁定信息
    int getPTZLockInfo(CameraCmd cmd);
    //抓图-返给前端二进制流
    String captureJPEGPicture(CameraCmd cmd);
    //抓图
    String picCutCate(CameraCmd cmd);
    //ptz 三坐标
    Map<String, Object> getPtz(CameraCmd cmd);
    //获取ptz范围
    Map<String, Object> getPtzScope(CameraCmd cmd);
    boolean setPtz(CameraCmd cmd);
    //设置零方位角
    boolean setZeroPtz(CameraCmd cmd);
    //引导目标位置
    boolean guideTargetPosition(CameraCmd cmd);
    //录像
    String record(CameraCmd cmd);
    //手动开始录像
    boolean recordStart(CameraCmd cmd);
    //手动停止录像-上传minio-返回录像url
    String recordStopToMinio(CameraCmd cmd);
    //停止录像-不上传minio
    boolean recordStopNotToMinio(CameraCmd cmd);
    //获取GIS信息数据
    Map<String, Object> getGisInfo(CameraCmd cmd);
}
package com.ruoyi.device.camera.service;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import java.util.Map;
public interface ICameraSdkService {
    //初始化登录
    void loginAll();
    //登录
    Boolean login(ArdCameras ardCamera);
    //注销
    boolean logout(String cameraId);
    //在线状态
    boolean isOnLine(CameraCmd cmd);
    //云台控制
    boolean pTZControl(CameraCmd cmd);
    //设置聚焦值
    boolean setFocusPos(CameraCmd cmd);
    //获取聚焦值
    int getFocusPos(CameraCmd cmd);
    //设置预置位
    boolean setPreset(CameraCmd cmd);
    //调用预置位
    boolean gotoPreset(CameraCmd cmd);
    //获取码流压缩参数
    Map<String, Object> getVideoCompressionCfg(CameraCmd cmd);
    //透雾
    boolean controlDefogcfg(CameraCmd cmd);
    //红外
    boolean controlInfrarecfg(CameraCmd cmd);
    //聚焦模式
    boolean controlFocusMode(CameraCmd cmd);
    //获取聚焦模式
    String getFocusMode(CameraCmd cmd);
    //云台加热
    boolean controlPTHeateRpwron(CameraCmd cmd);
    //镜头加热除冰
    boolean controlCameraDeicing(CameraCmd cmd);
    //配置锁定
    boolean controlLock(CameraCmd cmd);
    //配置解锁
    boolean controlUnLock(CameraCmd cmd);
    //获取云台锁定信息
    int getPTZLockInfo(CameraCmd cmd);
    //抓图-返给前端二进制流
    String captureJPEGPicture(CameraCmd cmd);
    //抓图
    String picCutCate(CameraCmd cmd);
    //ptz 三坐标
    Map<String, Object> getPtz(CameraCmd cmd);
    //获取ptz范围
    Map<String, Object> getPtzScope(CameraCmd cmd);
    boolean setPtz(CameraCmd cmd);
    //设置零方位角
    boolean setZeroPtz(CameraCmd cmd);
    //引导目标位置
    boolean guideTargetPosition(CameraCmd cmd);
    //录像
    String record(CameraCmd cmd);
    //手动开始录像
    boolean recordStart(CameraCmd cmd);
    //手动停止录像-上传minio-返回录像url
    String recordStopToMinio(CameraCmd cmd);
    //停止录像-不上传minio
    boolean recordStopNotToMinio(CameraCmd cmd);
    //获取GIS信息数据
    Map<String, Object> getGisInfo(CameraCmd cmd);
}
ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java
@@ -1,670 +1,686 @@
package com.ruoyi.device.camera.service.impl;
import com.ruoyi.common.annotation.SdkOperate;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.camera.service.ICameraSdkService;
import com.ruoyi.device.channel.domain.ArdChannel;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.module.RealPlayModule;
import com.ruoyi.device.dhsdk.service.IDhClientService;
import com.ruoyi.device.hiksdk.common.GlobalVariable;
import com.ruoyi.device.hiksdk.service.IHikClientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.ruoyi.device.dhsdk.lib.ToolKits.getErrorCodePrint;
import static com.ruoyi.device.dhsdk.module.LoginModule.netsdk;
import static com.ruoyi.device.hiksdk.sdk.HCNetSDK.NET_DVR_CHECK_USER_STATUS;
/**
 * @Description: 相机sdk业务
 * @ClassName: CameraSdkServiceImpl
 * @Author: 刘苏义
 * @Date: 2023年10月16日15:21:01
 **/
@Service
@Slf4j(topic = "SDK")
public class CameraSdkServiceImpl implements ICameraSdkService {
    @Resource
    private IArdCamerasService ardCamerasService;
    @Resource
    IHikClientService hikClientService;
    @Resource
    IDhClientService dhClientService;
    @Resource
    RedisCache redisCache;
    //初始化SDK
    @Override
    public void initSDK() {
        //初始化加载sdk库文件
        boolean initHIK = hikClientService.init();
        if (initHIK) {
            hikClientService.loginAll();//登录全部海康相机
        }
        Boolean initDH = dhClientService.init();
        if (initDH) {
            dhClientService.loginAll();//登录全部大华相机
        }
    }
    //登录
    @Override
    public Boolean login(ArdCameras ardCamera) {
        boolean result = false;
        try {
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    hikClientService.syncLogin(ardCamera);
                    result=true;
                } else if (factory.equals("2")) {
                    result = dhClientService.login(ardCamera);
                }
            }
        } catch (Exception ex) {
            log.error("登录异常:" + ex.getMessage());
            return false;
        }
        return result;
    }
    //注销
    @Override
    public boolean logout(String cameraId) {
        boolean result = false;
        try {
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.logout(cameraId);
                } else if (factory.equals("2")) {
                    result = dhClientService.logout(cameraId);
                }
            }
        } catch (Exception ex) {
            log.error("注销异常:" + ex.getMessage());
            return false;
        }
        return result;
    }
    //在线检测
    @Override
    public boolean isOnLine(CameraCmd cmd) {
        try {
            boolean onLine = false;
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    onLine = hikClientService.isOnLine(cmd);
                } else if (factory.equals("2")) {
                    onLine = dhClientService.isOnLine(cmd);
                }
            }
            return onLine;
        } catch (Exception ex) {
            log.error("检测在线异常:" + ex.getMessage());
            return false;
        }
    }
    //云台控制
    @SdkOperate
    @Override
    public boolean pTZControl(CameraCmd cmd) {
        try {
            boolean result = false;
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.pTZControlWithSpeed(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.pTZControl(cmd);
                }
            }
            return result;
        } catch (Exception ex) {
            log.error("ptz控制异常:" + ex.getMessage());
            return false;
        }
    }
    //设置聚焦值
    @Override
    public boolean setFocusPos(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setFocusPos(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setFocusPos(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置聚焦值异常:" + ex.getMessage());
        }
        return result;
    }
    //获取聚焦值
    @Override
    public int getFocusPos(CameraCmd cmd) {
        int result=0;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.getFocusPos(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.getFocusPos(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取聚焦值异常:" + ex.getMessage());
        }
        return result;
    }
    //设置预置位
    @Override
    public boolean setPreset(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setPreset(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setPreset(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置预置位异常:" + ex.getMessage());
        }
        return result;
    }
    //调用预置位
    @Override
    public boolean gotoPreset(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.gotoPreset(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.gotoPreset(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("调用预置位异常:" + ex.getMessage());
        }
        return result;
    }
    //获取码流压缩参数
    @Override
    public Map<String, Object> getVideoCompressionCfg(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getVideoCompressionCfg(cmd);
                } else if (factory.equals("2")) {
                    map = dhClientService.getVideoCompressionCfg(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取码流压缩参数异常:" + ex.getMessage());
        }
        return map;
    }
    //透雾开关
    @Override
    public boolean controlDefogcfg(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlDefogcfg(cmd);
                } else if (factory.equals("2")) {
                    //不支持
                }
            }
        } catch (Exception ex) {
            log.error("操控透雾异常:" + ex.getMessage());
        }
        return result;
    }
    //红外开关
    @Override
    public boolean controlInfrarecfg(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlInfrarecfg(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.controlInfrarecfg(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("操控红外异常:" + ex.getMessage());
        }
        return result;
    }
    //手动/自动聚焦
    @Override
    public boolean controlFocusMode(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlFocusMode(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.controlFocusMode(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("操控聚焦模式异常:" + ex.getMessage());
        }
        return result;
    }
    //获取聚焦模式
    @Override
    public String getFocusMode(CameraCmd cmd) {
        String result = "";
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.getFocusMode(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.getFocusMode(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取聚焦模式异常:" + ex.getMessage());
        }
        return result;
    }
    //云台加热
    @Override
    public boolean controlPTHeateRpwron(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlPTHeateRpwron(cmd);
                } else if (factory.equals("2")) {
                    //不支持
                }
            }
        } catch (Exception ex) {
            log.error("操控云台加热异常:" + ex.getMessage());
        }
        return result;
    }
    //镜头加热
    @Override
    public boolean controlCameraDeicing(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlCameraDeicing(cmd);
                } else if (factory.equals("2")) {
                    //不支持
                }
            }
        } catch (Exception ex) {
            log.error("操控云台加热异常:" + ex.getMessage());
        }
        return result;
    }
    //获取云台锁定信息
    @Override
    public int getPTZLockInfo(CameraCmd cmd) {
        int result = 99;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.getPTZLockInfo(cmd);
                } else if (factory.equals("2")) {
                }
            }
        } catch (Exception ex) {
            log.error("获取云台锁定信息异常:" + ex.getMessage());
        }
        return result;
    }
    @Override
    public String captureJPEGPicture(CameraCmd cmd) {
        return null;
    }
    //抓图
    @SdkOperate
    @Override
    public String picCutCate(CameraCmd cmd) {
       String url = "";
        try {
            //获取摄像头ID
            String cameraId = cmd.getCameraId();
            //从redis中获取摄像头信息
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                //获取摄像头工厂
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    //调用hikClientService的picCutCate方法
                    url = hikClientService.picCutCate(cmd);
                } else if (factory.equals("2")) {
                    //调用dhClientService的picCutCate方法
                    url = dhClientService.picCutCate(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("抓图异常:" + ex.getMessage());
        }
        return url;
    }
    //获取ptz
    @Override
    public Map<String, Object> getPtz(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getPtz(cmd);
                } else if (factory.equals("2")) {
                    map = dhClientService.getPtz(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取ptz异常:" + ex.getMessage());
        }
        return map;
    }
    //获取ptz范围
    @Override
    public Map<String, Object> getPtzScope(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getPtzScope(cmd);
                } else if (factory.equals("2")) {
                }
            }
        } catch (Exception ex) {
            log.error("获取ptz范围异常:" + ex.getMessage());
        }
        return map;
    }
    //设置ptz
    @SdkOperate
    @Override
    public boolean setPtz(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setPtz(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setPtz(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置ptz异常:" + ex.getMessage());
        }
        return result;
    }
    //设置零方位角
    @SdkOperate
    @Override
    public boolean setZeroPtz(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setZeroPtz(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setZeroPtz(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置零方位角异常:" + ex.getMessage());
        }
        return result;
    }
    //引导指向目标
    @SdkOperate
    @Override
    public boolean guideTargetPosition(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.guideTargetPosition(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.guideTargetPosition(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("引导指向目标异常:" + ex.getMessage());
        }
        return result;
    }
    /**
     * @描述 操控锁定
     * @参数 [userId, channelNum]
     * @返回值 boolean
     * @创建人 刘苏义
     * @创建时间 2023/1/17 16:36
     * @修改人和其它信息 0-解锁 1-锁定
     */
    @Override
    @SdkOperate
    public boolean controlLock(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();//申请锁的相机
        ArdCameras ardCameras = ardCamerasService.selectArdCamerasById(cameraId);
        Date now = new Date();
        now.setTime(now.getTime() + cmd.getExpired() * 1000);
        ardCameras.setOperatorExpired(now);//设置当前过期时间
        ardCamerasService.updateArdCameras(ardCameras);
        return true;
    }
    /**
     * @描述 操控解锁
     * @参数 [userId, channelNum]
     * @返回值 boolean
     * @创建人 刘苏义
     * @创建时间 2023/6/30 15:36
     * @修改人和其它信息
     */
    @Override
    public boolean controlUnLock(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();//申请解锁的相机
        String operator = cmd.getOperator();//申请者
        ArdCameras ardCameras = ardCamerasService.selectArdCamerasById(cameraId);
        if (ardCameras.getOperatorId().equals(operator)) {
            //如果解锁相机的当前用户是申请者,则清空该相机的过期时间
            ardCameras.setOperatorExpired(null);
            int i = ardCamerasService.updateArdCameras(ardCameras);
            if (i > 0) {
                log.debug(cameraId + "--解锁成功");
            }
        }
        return true;
    }
    //录像
    @SdkOperate
    @Override
    public String record(CameraCmd cmd) {
        String url = "";
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    url = hikClientService.record(cmd);
                } else if (factory.equals("2")) {
                    url = dhClientService.record(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("录像异常:" + ex.getMessage());
        }
        return url;
    }
    //开始录像
    @Override
    public boolean recordStart(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.recordStart(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.recordStart(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("开始录像异常:" + ex.getMessage());
        }
        return result;
    }
    //停止录像并存入minio
    @Override
    public String recordStopToMinio(CameraCmd cmd) {
        String url = "";
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    url = hikClientService.recordStopToMinio(cmd);
                } else if (factory.equals("2")) {
                    url = dhClientService.recordStopToMinio(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("停止录像异常:" + ex.getMessage());
        }
        return url;
    }
    //停止录像并不存入minio
    @Override
    public boolean recordStopNotToMinio(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.recordStopNotToMinio(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.recordStopNotToMinio(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("停止录像异常:" + ex.getMessage());
        }
        return result;
    }
    //获取相机架设参数
    @Override
    public Map<String, Object> getGisInfo(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getGisInfo(cmd);
                } else if (factory.equals("2")) {
                    map = dhClientService.getGisInfo(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取相机架设参数异常:" + ex.getMessage());
        }
        return map;
    }
}
package com.ruoyi.device.camera.service.impl;
import com.ruoyi.common.annotation.SdkOperate;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.camera.service.ICameraSdkService;
import com.ruoyi.device.channel.domain.ArdChannel;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.module.RealPlayModule;
import com.ruoyi.device.dhsdk.service.IDhClientService;
import com.ruoyi.device.hiksdk.common.GlobalVariable;
import com.ruoyi.device.hiksdk.service.IHikClientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.ruoyi.device.dhsdk.lib.ToolKits.getErrorCodePrint;
import static com.ruoyi.device.dhsdk.module.LoginModule.netsdk;
import static com.ruoyi.device.hiksdk.sdk.HCNetSDK.NET_DVR_CHECK_USER_STATUS;
/**
 * @Description: 相机sdk业务
 * @ClassName: CameraSdkServiceImpl
 * @Author: 刘苏义
 * @Date: 2023年10月16日15:21:01
 **/
@Service
@Slf4j(topic = "SDK")
public class CameraSdkServiceImpl implements ICameraSdkService {
    @Resource
    private IArdCamerasService ardCamerasService;
    @Resource
    IHikClientService hikClientService;
    @Resource
    IDhClientService dhClientService;
    @Resource
    RedisCache redisCache;
    //初始化SDK
    @Override
    public void loginAll() {
        hikClientService.loginAll();//登录全部海康相机
        dhClientService.loginAll();//登录全部大华相机
    }
    //登录
    @Override
    public Boolean login(ArdCameras ardCamera) {
        boolean result = false;
        try {
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    hikClientService.login(ardCamera);
                    result = true;
                } else if (factory.equals("2")) {
                    result = dhClientService.login(ardCamera);
                }
            }
        } catch (Exception ex) {
            log.error("登录异常:" + ex.getMessage());
            return false;
        }
        return result;
    }
    //注销
    @Override
    public boolean logout(String cameraId) {
        boolean result = false;
        try {
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.logout(cameraId);
                } else if (factory.equals("2")) {
                    result = dhClientService.logout(cameraId);
                }
            }
        } catch (Exception ex) {
            log.error("注销异常:" + ex.getMessage());
            return false;
        }
        return result;
    }
    //在线检测
    @Override
    public boolean isOnLine(CameraCmd cmd) {
        try {
            boolean onLine = false;
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    onLine = hikClientService.isOnLine(cmd);
                } else if (factory.equals("2")) {
                    onLine = dhClientService.isOnLine(cmd);
                }
            }
            return onLine;
        } catch (Exception ex) {
            log.error("检测在线异常:" + ex.getMessage());
            return false;
        }
    }
    //云台控制
    @SdkOperate
    @Override
    public boolean pTZControl(CameraCmd cmd) {
        try {
            boolean result = false;
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.pTZControlWithSpeed(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.pTZControl(cmd);
                }
            }
            return result;
        } catch (Exception ex) {
            log.error("ptz控制异常:" + ex.getMessage());
            return false;
        }
    }
    //设置聚焦值
    @Override
    public boolean setFocusPos(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setFocusPos(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setFocusPos(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置聚焦值异常:" + ex.getMessage());
        }
        return result;
    }
    //获取聚焦值
    @Override
    public int getFocusPos(CameraCmd cmd) {
        int result = 0;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.getFocusPos(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.getFocusPos(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取聚焦值异常:" + ex.getMessage());
        }
        return result;
    }
    //设置预置位
    @Override
    public boolean setPreset(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setPreset(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setPreset(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置预置位异常:" + ex.getMessage());
        }
        return result;
    }
    //调用预置位
    @Override
    public boolean gotoPreset(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.gotoPreset(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.gotoPreset(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("调用预置位异常:" + ex.getMessage());
        }
        return result;
    }
    //获取码流压缩参数
    @Override
    public Map<String, Object> getVideoCompressionCfg(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getVideoCompressionCfg(cmd);
                } else if (factory.equals("2")) {
                    map = dhClientService.getVideoCompressionCfg(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取码流压缩参数异常:" + ex.getMessage());
        }
        return map;
    }
    //透雾开关
    @Override
    public boolean controlDefogcfg(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlDefogcfg(cmd);
                } else if (factory.equals("2")) {
                    //不支持
                }
            }
        } catch (Exception ex) {
            log.error("操控透雾异常:" + ex.getMessage());
        }
        return result;
    }
    //红外开关
    @Override
    public boolean controlInfrarecfg(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlInfrarecfg(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.controlInfrarecfg(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("操控红外异常:" + ex.getMessage());
        }
        return result;
    }
    //手动/自动聚焦
    @Override
    public boolean controlFocusMode(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlFocusMode(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.controlFocusMode(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("操控聚焦模式异常:" + ex.getMessage());
        }
        return result;
    }
    //获取聚焦模式
    @Override
    public String getFocusMode(CameraCmd cmd) {
        String result = "";
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.getFocusMode(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.getFocusMode(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取聚焦模式异常:" + ex.getMessage());
        }
        return result;
    }
    //云台加热
    @Override
    public boolean controlPTHeateRpwron(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlPTHeateRpwron(cmd);
                } else if (factory.equals("2")) {
                    //不支持
                }
            }
        } catch (Exception ex) {
            log.error("操控云台加热异常:" + ex.getMessage());
        }
        return result;
    }
    //镜头加热
    @Override
    public boolean controlCameraDeicing(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.controlCameraDeicing(cmd);
                } else if (factory.equals("2")) {
                    //不支持
                }
            }
        } catch (Exception ex) {
            log.error("操控云台加热异常:" + ex.getMessage());
        }
        return result;
    }
    //获取云台锁定信息
    @Override
    public int getPTZLockInfo(CameraCmd cmd) {
        int result = 99;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.getPTZLockInfo(cmd);
                } else if (factory.equals("2")) {
                }
            }
        } catch (Exception ex) {
            log.error("获取云台锁定信息异常:" + ex.getMessage());
        }
        return result;
    }
    @Override
    public String captureJPEGPicture(CameraCmd cmd) {
        return null;
    }
    //抓图
    @SdkOperate
    @Override
    public String picCutCate(CameraCmd cmd) {
        String url = "";
        try {
            //获取摄像头ID
            String cameraId = cmd.getCameraId();
            //从redis中获取摄像头信息
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                //获取摄像头工厂
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    //调用hikClientService的picCutCate方法
                    url = hikClientService.picCutCate(cmd);
                } else if (factory.equals("2")) {
                    //调用dhClientService的picCutCate方法
                    url = dhClientService.picCutCate(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("抓图异常:" + ex.getMessage());
        }
        return url;
    }
    //获取ptz
    @Override
    public Map<String, Object> getPtz(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getPtz(cmd);
                } else if (factory.equals("2")) {
                    map = dhClientService.getPtz(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取ptz异常:" + ex.getMessage());
        }
        return map;
    }
    //获取ptz范围
    @Override
    public Map<String, Object> getPtzScope(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getPtzScope(cmd);
                } else if (factory.equals("2")) {
                }
            }
        } catch (Exception ex) {
            log.error("获取ptz范围异常:" + ex.getMessage());
        }
        return map;
    }
    //设置ptz
    @SdkOperate
    @Override
    public boolean setPtz(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setPtz(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setPtz(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置ptz异常:" + ex.getMessage());
        }
        return result;
    }
    //设置零方位角
    @SdkOperate
    @Override
    public boolean setZeroPtz(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.setZeroPtz(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.setZeroPtz(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("设置零方位角异常:" + ex.getMessage());
        }
        return result;
    }
    //引导指向目标
    @SdkOperate
    @Override
    public boolean guideTargetPosition(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.guideTargetPosition(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.guideTargetPosition(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("引导指向目标异常:" + ex.getMessage());
        }
        return result;
    }
    /**
     * @描述 操控锁定
     * @参数 [userId, channelNum]
     * @返回值 boolean
     * @创建人 刘苏义
     * @创建时间 2023/1/17 16:36
     * @修改人和其它信息 0-解锁 1-锁定
     */
    @Override
    @SdkOperate
    public boolean controlLock(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();//申请锁的相机
        ArdCameras ardCameras = ardCamerasService.selectArdCamerasById(cameraId);
        Date now = new Date();
        now.setTime(now.getTime() + cmd.getExpired() * 1000);
        ardCameras.setOperatorExpired(now);//设置当前过期时间
        ardCamerasService.updateArdCameras(ardCameras);
        return true;
    }
    /**
     * @描述 操控解锁
     * @参数 [userId, channelNum]
     * @返回值 boolean
     * @创建人 刘苏义
     * @创建时间 2023/6/30 15:36
     * @修改人和其它信息
     */
    @Override
    public boolean controlUnLock(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();//申请解锁的相机
        String operator = cmd.getOperator();//申请者
        ArdCameras ardCameras = ardCamerasService.selectArdCamerasById(cameraId);
        if (ardCameras.getOperatorId().equals(operator)) {
            //如果解锁相机的当前用户是申请者,则清空该相机的过期时间
            ardCameras.setOperatorExpired(null);
            int i = ardCamerasService.updateArdCameras(ardCameras);
            if (i > 0) {
                log.debug(cameraId + "--解锁成功");
            }
        }
        return true;
    }
    //录像
    @SdkOperate
    @Override
    public String record(CameraCmd cmd) {
        String url = "";
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    url = hikClientService.record(cmd);
                } else if (factory.equals("2")) {
                    url = dhClientService.record(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("录像异常:" + ex.getMessage());
        }
        return url;
    }
    //开始录像
    @Override
    public boolean recordStart(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.recordStart(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.recordStart(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("开始录像异常:" + ex.getMessage());
        }
        return result;
    }
    //停止录像并存入minio
    @Override
    public String recordStopToMinio(CameraCmd cmd) {
        String url = "";
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    url = hikClientService.recordStopToMinio(cmd);
                } else if (factory.equals("2")) {
                    url = dhClientService.recordStopToMinio(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("停止录像异常:" + ex.getMessage());
        }
        return url;
    }
    //停止录像并不存入minio
    @Override
    public boolean recordStopNotToMinio(CameraCmd cmd) {
        boolean result = false;
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    result = hikClientService.recordStopNotToMinio(cmd);
                } else if (factory.equals("2")) {
                    result = dhClientService.recordStopNotToMinio(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("停止录像异常:" + ex.getMessage());
        }
        return result;
    }
    //获取相机架设参数
    @Override
    public Map<String, Object> getGisInfo(CameraCmd cmd) {
        Map<String, Object> map = new HashMap<>();
        try {
            String cameraId = cmd.getCameraId();
            ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId);
            if (ardCamera != null) {
                String factory = ardCamera.getFactory();
                if (factory.equals("1")) {
                    map = hikClientService.getGisInfo(cmd);
                } else if (factory.equals("2")) {
                    map = dhClientService.getGisInfo(cmd);
                }
            }
        } catch (Exception ex) {
            log.error("获取相机架设参数异常:" + ex.getMessage());
        }
        return map;
    }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/LibraryLoad.java
@@ -1,189 +1,196 @@
package com.ruoyi.device.dhsdk.lib;
import com.ruoyi.device.dhsdk.lib.DynamicParseUtil;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
/**
 * @author 47081
 * @version 1.0
 * @description 动态库加载
 * @date 2020/11/14
 */
public class LibraryLoad {
  private static final String ARCH_WINDOWS = "win";
  private static final String ARCH_LINUX = "linux";
  private static final String ARCH_MAC = "mac";
  private static final int PREFIX_64 = 64;
  private static final int PREFIX_32 = 32;
  private static final String PREFIX_ARM = "ARM";
  private static final String EXTERNAL_WIN = ".dll";
  private static final String EXTERNAL_LINUX = ".so";
  private static final String EXTERNAL_MAC = ".dylib";
  private static DynamicParseUtil dynamicParseUtil;
  /** 当前读取的目录 */
  private static String currentFold;
  /** 动态库需要写入的目录 */
  private static String EXTRACT_PATH = System.getProperty("java.io.tmpdir");
  private static boolean written = false;
  /**
   * 设置动态库写入的路径,适用于需要自定义加载路径的用户
   *
   * @param path 动态库写入的文件夹,从该文件夹下加载sdk的动态库
   */
  public static void setExtractPath(String path) {
    EXTRACT_PATH = path;
  }
  public static String  getExtractPath() {
    return EXTRACT_PATH;
      }
  /** 动态库路径 */
  private static String INNER_PATH;
  // private static final String EXTERNAL_MAC = ".so";
  private static String extractNetSDKLib(String libName) {
    return extractLibrary(libName);
  }
  public static String getLoadLibrary(String libraryName) {
    currentFold = getLibraryFold();
    if (dynamicParseUtil == null) {
      try {
        dynamicParseUtil =
            new DynamicParseUtil(
                LibraryLoad.class.getClassLoader().getResourceAsStream("dynamic-lib-load.xml"));
        if (!written) {
          for (String libName : dynamicParseUtil.getLibsSystem(currentFold)) {
            extractLibrary(libName);
          }
          written = true;
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    String fullName = getLibraryName(libraryName);
    String path = EXTRACT_PATH;
    if (!(EXTRACT_PATH.endsWith("/") || EXTRACT_PATH.endsWith("\\"))) {
      path = EXTRACT_PATH + "/";
    }
    System.out.println("load library: " + path + fullName);
    return path + fullName;
  }
  /**
   * 将jar包里的动态库写入到系统缓存目录,使用绝对路径加载动态库
   *
   * @param libName
   * @return
   */
  private static String extractLibrary(String libName) {
    return extractLibrary("", libName);
  }
  /**
   * 相对路径文件夹
   *
   * @param relativePath 相对路径
   * @param libName 动态库路径
   * @return
   */
  private static String extractLibrary(String relativePath, String libName) {
    if (libName.trim().equals("")) {
      return "";
    }
    String libFullName = getLibraryName(libName);
    String dir = getLibraryFold();
    if (!(relativePath.endsWith("/") || relativePath.endsWith("\\"))) {
      relativePath = relativePath + "/";
    }
    String fileName = relativePath + dir + "/" + libFullName;
    InputStream in = LibraryLoad.class.getResourceAsStream(fileName);
    BufferedInputStream reader;
    FileOutputStream writer;
    File extractedLibFile = null;
    try {
      if (in == null) {
        in = new FileInputStream(fileName);
      }
      String nativeTempDir = EXTRACT_PATH;
      if (!(nativeTempDir.endsWith("/") || nativeTempDir.endsWith("\\"))) {
        nativeTempDir = nativeTempDir + "/";
      }
      extractedLibFile = new File(nativeTempDir + libFullName);
      reader = new BufferedInputStream(in);
      writer = new FileOutputStream(extractedLibFile);
      byte[] buffer = new byte[1024];
      while (true) {
        int len = reader.read(buffer);
        if (len == 0 || len == -1) break;
        writer.write(buffer, 0, len);
      }
      reader.close();
      writer.close();
      in.close();
    } catch (Exception e) {
      //System.out.println("dynamic file[ "+ fileName+ " ] not found in project.please ensure you need this library.");
    }
    return extractedLibFile != null ? extractedLibFile.getAbsolutePath() : "";
  }
  /**
   * 获取动态库完整名称
   *
   * @param libName
   * @return
   */
  private static String getLibraryName(String libName) {
    String dir = currentFold;
    String libPrefix = "";
    String libExtension = EXTERNAL_WIN;
    if (!dir.contains("win")) {
      libPrefix = "lib";
      if (dir.contains("linux")) {
        libExtension = EXTERNAL_LINUX;
      } else {
        // libExtension=".dylib";
        libExtension = EXTERNAL_MAC;
      }
    }
    libName = dynamicParseUtil.compareLibName(currentFold, libName);
    // 动态库以lib开头,则不添加lib前缀
    // 以lib开头的库则不添加lib前缀
    return (libName.startsWith("lib") ? "" : libPrefix) + libName + libExtension;
  }
  // 获取系统对应的动态库文件夹
  private static String getLibraryFold() {
    String osType;
    String osName = System.getProperty("os.name");
    if (osName.toLowerCase().startsWith("linux")) {
      osType = ARCH_LINUX;
    } else if (osName.toLowerCase().startsWith("mac")
        || osName.toLowerCase().startsWith("darwin")) {
      osType = ARCH_MAC;
    } else if (osName.toLowerCase().startsWith("windows")) {
      osType = ARCH_WINDOWS;
    } else {
      osType = "";
    }
    String arch = System.getProperty("os.arch");
    arch = arch.toLowerCase().trim();
    if ("i386".equals(arch) || "i686".equals(arch)||"x86".equals(arch)) {
      arch = PREFIX_32 + "";
    } else if ("x86_64".equals(arch) || "amd64".equals(arch)) {
      arch = PREFIX_64 + "";
    } else if (arch.startsWith("arm")) {
      arch = PREFIX_ARM + "";
    }
    return osType + arch;
  }
}
package com.ruoyi.device.dhsdk.lib;
import com.ruoyi.device.dhsdk.lib.DynamicParseUtil;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
/**
 * @author 47081
 * @version 1.0
 * @description 动态库加载
 * @date 2020/11/14
 */
public class LibraryLoad {
  private static final String ARCH_WINDOWS = "win";
  private static final String ARCH_LINUX = "linux";
  private static final String ARCH_MAC = "mac";
  private static final int PREFIX_64 = 64;
  private static final int PREFIX_32 = 32;
  private static final String PREFIX_ARM = "ARM";
  private static final String EXTERNAL_WIN = ".dll";
  private static final String EXTERNAL_LINUX = ".so";
  private static final String EXTERNAL_MAC = ".dylib";
  private static DynamicParseUtil dynamicParseUtil;
  /** 当前读取的目录 */
  private static String currentFold;
  /** 动态库需要写入的目录 */
  private static String EXTRACT_PATH = System.getProperty("java.io.tmpdir");
  private static boolean written = false;
  /**
   * 设置动态库写入的路径,适用于需要自定义加载路径的用户
   *
   * @param path 动态库写入的文件夹,从该文件夹下加载sdk的动态库
   */
  public static void setExtractPath(String path) {
    EXTRACT_PATH = path;
  }
  public static String  getExtractPath() {
    return EXTRACT_PATH;
      }
  /** 动态库路径 */
  private static String INNER_PATH;
  // private static final String EXTERNAL_MAC = ".so";
  private static String extractNetSDKLib(String libName) {
    return extractLibrary(libName);
  }
  public static String getLoadLibrary(String libraryName) {
    currentFold = getLibraryFold();
    if (dynamicParseUtil == null) {
      try {
        dynamicParseUtil =
            new DynamicParseUtil(
                LibraryLoad.class.getClassLoader().getResourceAsStream("dynamic-lib-load.xml"));
        if (!written) {
          for (String libName : dynamicParseUtil.getLibsSystem(currentFold)) {
            extractLibrary(libName);
          }
          written = true;
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    String fullName = getLibraryName(libraryName);
    String path = EXTRACT_PATH;
    if (!(EXTRACT_PATH.endsWith("/") || EXTRACT_PATH.endsWith("\\"))) {
      path = EXTRACT_PATH + "/";
    }
    System.out.println("load library: " + path + fullName);
    return path + fullName;
  }
  /**
   * 将jar包里的动态库写入到系统缓存目录,使用绝对路径加载动态库
   *
   * @param libName
   * @return
   */
  private static String extractLibrary(String libName) {
    return extractLibrary("/lib", libName);
  }
    /**
     * 相对路径文件夹
     *
     * @param relativePath 相对路径
     * @param libName      动态库路径
     * @return
     */
    private static String extractLibrary(String relativePath, String libName) {
        if (libName.trim().equals("")) {
            return "";
        }
        String libFullName = getLibraryName(libName);
        String dir = getLibraryFold();
        if (!(relativePath.endsWith("/") || relativePath.endsWith("\\"))) {
            relativePath = relativePath + "/";
        }
        String fileName = relativePath + dir + "/" + libFullName;
        InputStream in = LibraryLoad.class.getResourceAsStream(fileName);
        BufferedInputStream reader;
        FileOutputStream writer;
        File extractedLibFile = null;
        try {
            if (in == null) {
                in = new FileInputStream(fileName);
            }
            String nativeTempDir = EXTRACT_PATH;
            if (!(nativeTempDir.endsWith("/") || nativeTempDir.endsWith("\\"))) {
                nativeTempDir = nativeTempDir + "/";
            }
            extractedLibFile = new File(nativeTempDir + libFullName);
            reader = new BufferedInputStream(in);
            // 检查文件夹是否存在,如果不存在则创建
            File parentDir = extractedLibFile.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
            writer = new FileOutputStream(extractedLibFile);
            byte[] buffer = new byte[1024];
            while (true) {
                int len = reader.read(buffer);
                if (len == 0 || len == -1) break;
                writer.write(buffer, 0, len);
            }
            reader.close();
            writer.close();
            in.close();
        } catch (Exception e) {
            System.out.println("dynamic file[ " + fileName + " ] not found in project.please ensure you need this library.");
        }
        return extractedLibFile != null ? extractedLibFile.getAbsolutePath() : "";
    }
  /**
   * 获取动态库完整名称
   *
   * @param libName
   * @return
   */
  private static String getLibraryName(String libName) {
    String dir = currentFold;
    String libPrefix = "";
    String libExtension = EXTERNAL_WIN;
    if (!dir.contains("win")) {
      libPrefix = "lib";
      if (dir.contains("linux")) {
        libExtension = EXTERNAL_LINUX;
      } else {
        // libExtension=".dylib";
        libExtension = EXTERNAL_MAC;
      }
    }
    libName = dynamicParseUtil.compareLibName(currentFold, libName);
    // 动态库以lib开头,则不添加lib前缀
    // 以lib开头的库则不添加lib前缀
    return (libName.startsWith("lib") ? "" : libPrefix) + libName + libExtension;
  }
  // 获取系统对应的动态库文件夹
  private static String getLibraryFold() {
    String osType;
    String osName = System.getProperty("os.name");
    if (osName.toLowerCase().startsWith("linux")) {
      osType = ARCH_LINUX;
    } else if (osName.toLowerCase().startsWith("mac")
        || osName.toLowerCase().startsWith("darwin")) {
      osType = ARCH_MAC;
    } else if (osName.toLowerCase().startsWith("windows")) {
      osType = ARCH_WINDOWS;
    } else {
      osType = "";
    }
    String arch = System.getProperty("os.arch");
    arch = arch.toLowerCase().trim();
    if ("i386".equals(arch) || "i686".equals(arch)||"x86".equals(arch)) {
      arch = PREFIX_32 + "";
    } else if ("x86_64".equals(arch) || "amd64".equals(arch)) {
      arch = PREFIX_64 + "";
    } else if (arch.startsWith("arm")) {
      arch = PREFIX_ARM + "";
    }
    return osType + arch;
  }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/NetSDKLib.java
文件太大
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/Utils.java
@@ -1,210 +1,210 @@
package com.ruoyi.device.dhsdk.lib;
import com.sun.jna.IntegerType;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Structure;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class Utils {
    public Utils() {
    }
    /**
     * 获取系统对应的编码
     *
     */
    public static String getPlatformEncode() {
        String encode = "";
        String osPrefix = getOsPrefix();
        if (osPrefix.toLowerCase().startsWith("win32")) {
            encode = "GBK";
        } else if (osPrefix.toLowerCase().startsWith("linux")) {
            encode = "UTF-8";
        }else if(osPrefix.toLowerCase().startsWith("mac")){
            encode="UTF-8";
        }
        if(encode.isEmpty()){
            encode="UTF-8";
        }
        return encode;
    }
    // 获取操作平台信息
    public static String getOsPrefix() {
        String arch = System.getProperty("os.arch").toLowerCase();
        final String name = System.getProperty("os.name");
        String osPrefix;
        switch (Platform.getOSType()) {
            case Platform.WINDOWS: {
                if ("i386".equals(arch))
                    arch = "x86";
                osPrefix = "win32-" + arch;
            }
            break;
            case Platform.LINUX: {
                if ("x86".equals(arch)) {
                    arch = "i386";
                } else if ("x86_64".equals(arch)) {
                    arch = "amd64";
                }
                osPrefix = "linux-" + arch;
            }
            break;
            case Platform.MAC: {
                //mac系统的os.arch都是ppc(老版本的mac是powerpc,已经基本不用)看不出系统位数,使用下面的参数表示
                arch = System.getProperty("sun.arch.data.model");
                osPrefix = "mac-" + arch;
            }
            break;
            default: {
                osPrefix = name.toLowerCase();
                if ("x86".equals(arch)) {
                    arch = "i386";
                }
                if ("x86_64".equals(arch)) {
                    arch = "amd64";
                }
                int space = osPrefix.indexOf(" ");
                if (space != -1) {
                    osPrefix = osPrefix.substring(0, space);
                }
                osPrefix += "-" + arch;
            }
            break;
        }
        return osPrefix;
    }
    public static String getOsName() {
        String osName = "";
        String osPrefix = getOsPrefix();
        if (osPrefix.toLowerCase().startsWith("win32-x86")
                || osPrefix.toLowerCase().startsWith("win32-amd64")) {
            osName = "win";
        } else if (osPrefix.toLowerCase().startsWith("linux-i386")
                || osPrefix.toLowerCase().startsWith("linux-amd64")) {
            osName = "linux";
        } else if (osPrefix.toLowerCase().startsWith("mac-64")
                || osPrefix.toLowerCase().startsWith("mac-32")) {
            osName = "mac";
        }
        return osName;
    }
    // 获取加载库
    public static String getLoadLibrary(String library) {
        if (isChecking()) {
            return null;
        }
        String loadLibrary = "";
        String osPrefix = getOsPrefix();
        if (osPrefix.toLowerCase().startsWith("win32-x86")) {
            loadLibrary = "./libs/win32/";
        } else if (osPrefix.toLowerCase().startsWith("win32-amd64")) {
            loadLibrary = "./libs/win64/";
        } else if (osPrefix.toLowerCase().startsWith("linux-i386")) {
            loadLibrary = "";
        } else if (osPrefix.toLowerCase().startsWith("linux-amd64")) {
            loadLibrary = "";
        } else if (osPrefix.toLowerCase().startsWith("mac-64")) {
            loadLibrary = "";
        }
//        else if(osPrefix.toLowerCase().startsWith("mac-32")) {
//            loadLibrary = "";
//        }  32位mac版本基本没人用了,暂时不用
        System.out.printf("加载库[%s]\n", loadLibrary + library);
        return loadLibrary + library;
    }
    private static boolean checking = false;
    public static void setChecking() {
        checking = true;
    }
    public static void clearChecking() {
        checking = false;
    }
    public static boolean isChecking() {
        return checking;
    }
    public static class LLong extends IntegerType {
        private static final long serialVersionUID = 1L;
        /**
         * Size of a native long, in bytes.
         */
        public static int size;
        static {
            size = Native.LONG_SIZE;
            if (Utils.getOsPrefix().toLowerCase().equals("linux-amd64")
                    || Utils.getOsPrefix().toLowerCase().equals("win32-amd64")
                    || Utils.getOsPrefix().toLowerCase().equals("mac-64")) {
                size = 8;
            } else if (Utils.getOsPrefix().toLowerCase().equals("linux-i386")
                    || Utils.getOsPrefix().toLowerCase().equals("win32-x86")) {
                size = 4;
            }
        }
        /**
         * Create a zero-valued LLong.
         */
        public LLong() {
            this(0);
        }
        /**
         * Create a LLong with the given value.
         */
        public LLong(long value) {
            super(size, value);
        }
    }
    public static class SdkStructure extends Structure {
        @Override
        protected List<String> getFieldOrder() {
            List<String> fieldOrderList = new ArrayList<String>();
            for (Class<?> cls = getClass();
                 !cls.equals(NetSDKLib.SdkStructure.class);
                 cls = cls.getSuperclass()) {
                Field[] fields = cls.getDeclaredFields();
                int modifiers;
                for (Field field : fields) {
                    modifiers = field.getModifiers();
                    if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
                        continue;
                    }
                    fieldOrderList.add(field.getName());
                }
            }
            //            System.out.println(fieldOrderList);
            return fieldOrderList;
        }
    }
    // 获取当前时间
    public static String getDate() {
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDate.format(new java.util.Date())
                .replace(" ", "_").replace(":", "-");
    }
}
package com.ruoyi.device.dhsdk.lib;
import com.sun.jna.IntegerType;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Structure;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class Utils {
    public Utils() {
    }
    /**
     * 获取系统对应的编码
     *
     */
    public static String getPlatformEncode() {
        String encode = "";
        String osPrefix = getOsPrefix();
        if (osPrefix.toLowerCase().startsWith("win32")) {
            encode = "GBK";
        } else if (osPrefix.toLowerCase().startsWith("linux")) {
            encode = "UTF-8";
        }else if(osPrefix.toLowerCase().startsWith("mac")){
            encode="UTF-8";
        }
        if(encode.isEmpty()){
            encode="UTF-8";
        }
        return encode;
    }
    // 获取操作平台信息
    public static String getOsPrefix() {
        String arch = System.getProperty("os.arch").toLowerCase();
        final String name = System.getProperty("os.name");
        String osPrefix;
        switch (Platform.getOSType()) {
            case Platform.WINDOWS: {
                if ("i386".equals(arch))
                    arch = "x86";
                osPrefix = "win32-" + arch;
            }
            break;
            case Platform.LINUX: {
                if ("x86".equals(arch)) {
                    arch = "i386";
                } else if ("x86_64".equals(arch)) {
                    arch = "amd64";
                }
                osPrefix = "linux-" + arch;
            }
            break;
            case Platform.MAC: {
                //mac系统的os.arch都是ppc(老版本的mac是powerpc,已经基本不用)看不出系统位数,使用下面的参数表示
                arch = System.getProperty("sun.arch.data.model");
                osPrefix = "mac-" + arch;
            }
            break;
            default: {
                osPrefix = name.toLowerCase();
                if ("x86".equals(arch)) {
                    arch = "i386";
                }
                if ("x86_64".equals(arch)) {
                    arch = "amd64";
                }
                int space = osPrefix.indexOf(" ");
                if (space != -1) {
                    osPrefix = osPrefix.substring(0, space);
                }
                osPrefix += "-" + arch;
            }
            break;
        }
        return osPrefix;
    }
    public static String getOsName() {
        String osName = "";
        String osPrefix = getOsPrefix();
        if (osPrefix.toLowerCase().startsWith("win32-x86")
                || osPrefix.toLowerCase().startsWith("win32-amd64")) {
            osName = "win";
        } else if (osPrefix.toLowerCase().startsWith("linux-i386")
                || osPrefix.toLowerCase().startsWith("linux-amd64")) {
            osName = "linux";
        } else if (osPrefix.toLowerCase().startsWith("mac-64")
                || osPrefix.toLowerCase().startsWith("mac-32")) {
            osName = "mac";
        }
        return osName;
    }
    // 获取加载库
    public static String getLoadLibrary(String library) {
        if (isChecking()) {
            return null;
        }
        String loadLibrary = "";
        String osPrefix = getOsPrefix();
        if (osPrefix.toLowerCase().startsWith("win32-x86")) {
            loadLibrary = "./lib/win32/";
        } else if (osPrefix.toLowerCase().startsWith("win32-amd64")) {
            loadLibrary = "./lib/win64/";
        } else if (osPrefix.toLowerCase().startsWith("linux-i386")) {
            loadLibrary = "";
        } else if (osPrefix.toLowerCase().startsWith("linux-amd64")) {
            loadLibrary = "";
        } else if (osPrefix.toLowerCase().startsWith("mac-64")) {
            loadLibrary = "";
        }
//        else if(osPrefix.toLowerCase().startsWith("mac-32")) {
//            loadLibrary = "";
//        }  32位mac版本基本没人用了,暂时不用
        System.out.printf("加载库[%s]\n", loadLibrary + library);
        return loadLibrary + library;
    }
    private static boolean checking = false;
    public static void setChecking() {
        checking = true;
    }
    public static void clearChecking() {
        checking = false;
    }
    public static boolean isChecking() {
        return checking;
    }
    public static class LLong extends IntegerType {
        private static final long serialVersionUID = 1L;
        /**
         * Size of a native long, in bytes.
         */
        public static int size;
        static {
            size = Native.LONG_SIZE;
            if (Utils.getOsPrefix().toLowerCase().equals("linux-amd64")
                    || Utils.getOsPrefix().toLowerCase().equals("win32-amd64")
                    || Utils.getOsPrefix().toLowerCase().equals("mac-64")) {
                size = 8;
            } else if (Utils.getOsPrefix().toLowerCase().equals("linux-i386")
                    || Utils.getOsPrefix().toLowerCase().equals("win32-x86")) {
                size = 4;
            }
        }
        /**
         * Create a zero-valued LLong.
         */
        public LLong() {
            this(0);
        }
        /**
         * Create a LLong with the given value.
         */
        public LLong(long value) {
            super(size, value);
        }
    }
    public static class SdkStructure extends Structure {
        @Override
        protected List<String> getFieldOrder() {
            List<String> fieldOrderList = new ArrayList<String>();
            for (Class<?> cls = getClass();
                 !cls.equals(NetSDKLib.SdkStructure.class);
                 cls = cls.getSuperclass()) {
                Field[] fields = cls.getDeclaredFields();
                int modifiers;
                for (Field field : fields) {
                    modifiers = field.getModifiers();
                    if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
                        continue;
                    }
                    fieldOrderList.add(field.getName());
                }
            }
            //            System.out.println(fieldOrderList);
            return fieldOrderList;
        }
    }
    // 获取当前时间
    public static String getDate() {
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDate.format(new java.util.Date())
                .replace(" ", "_").replace(":", "-");
    }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/CFG_MOTION_INFO.java
@@ -1,125 +1,125 @@
package com.ruoyi.device.dhsdk.lib.structure;
/**
 * @author 47081
 * @desc
 * @version 1.0.0
 * @date 2021/4/9
 */
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.sun.jna.ptr.IntByReference;
import java.util.Arrays;
import static com.ruoyi.device.dhsdk.lib.NetSDKLib.MAX_REC_TSECT;
import static com.ruoyi.device.dhsdk.lib.constant.SDKStructureFieldLenth.*;
/**
 * @author 47081
 * @description 动态监测报警配置,对应接口 {@link
 *     com.netsdk.lib.NetSDKLib#CLIENT_GetNewDevConfig(NetSDKLib.LLong, String, int, byte[], int,
 *     IntByReference, int)}和{@link NetSDKLib#CLIENT_SetNewDevConfig(NetSDKLib.LLong, String, int,
 *     byte[], int, IntByReference, IntByReference, int)}
 * @date 2021/4/9
 * @version 1.0
 */
public class CFG_MOTION_INFO extends NetSDKLib.SdkStructure {
  /** 报警通道号(0开始), nVersion=1时,此字段无效 */
  public int nChannelID;
  /** 使能开关 */
  public int bEnable;
  /** 一代动检灵敏度1~6 */
  public int nSenseLevel;
  /** 一代动态检测区域的行数 */
  public int nMotionRow;
  /** 一代动态检测区域的列数 */
  public int nMotionCol;
  /** 一代检测区域,最多32*32块区域 */
  public BYTE_32[] byRegion = new BYTE_32[MAX_MOTION_ROW];
  /** 报警联动 */
  public NetSDKLib.CFG_ALARM_MSG_HANDLE stuEventHandler=new NetSDKLib.CFG_ALARM_MSG_HANDLE();
  /** 事件响应时间段,时间段获取和设置以此成员为准,忽略 stuEventHandler 中的stuTimeSection */
  public NetSDKLib.CFG_TIME_SECTION[] stuTimeSection =
          new NetSDKLib.CFG_TIME_SECTION[WEEK_DAY_NUM * MAX_REC_TSECT];
  /** 0, 1, 由能力集确定, 只读, 等于1时以下字段有效 */
  public int nVersion;
  /** 只读,决定nSenseLevel是否有效 */
  public int bSenseLevelEn;
  /** 只读,面积占用比使能, 决定nVolumeRatio是否有效 */
  public int bVRatioEn;
  /** 一代动检的面积占用比,1-100 */
  public int nVolumeRatio;
  /** 只读,灵敏度使能,决定nSubRatio值是否有效 */
  public int bSRatioEn;
  /** 一代动检的残差阈值, 1-100 */
  public int nSubRatio;
  /** 此字段及以下两个字段已废弃 */
  public int abWindow;
  /** 视频窗口个数 */
  @Deprecated public int nWindowCount;
  /** 视频窗口数组 */
  @Deprecated
  public CFG_MOTION_WINDOW[] stuWindows = new CFG_MOTION_WINDOW[MAX_MOTION_WINDOW];
  /** 只读, 1:nRegionCount,stuRegion有效 0:nMotionRow,nMotionCol,byRegion有效 */
  public int abDetectRegion;
  /** 三代动态检测区域个数 */
  public int nRegionCount;
  /** 三代动态检测区域 */
  public CFG_DETECT_REGION[] stuRegion =
    new CFG_DETECT_REGION[MAX_MOTION_WINDOW];
  /** 前端动态检测联动 */
  public NetSDKLib.CFG_ALARM_MSG_HANDLE stuRemoteEventHandler=new NetSDKLib.CFG_ALARM_MSG_HANDLE();
  /** 前端动态检测联动, 事件响应时间段,时间段获取和设置以此成员为准,忽略 stuRemoteEventHandler中的stuTimeSection */
  public NetSDKLib.CFG_TIME_SECTION[] stuRemoteTimeSection =
          new NetSDKLib.CFG_TIME_SECTION[WEEK_DAY_NUM * MAX_REC_TSECT];
  @Override
  public String toString() {
    return "CFG_MOTION_INFO{" +
            "nChannelID=" + nChannelID +
            ", bEnable=" + bEnable +
            ", nSenseLevel=" + nSenseLevel +
            ", nMotionRow=" + nMotionRow +
            ", nMotionCol=" + nMotionCol +
            ", byRegion=" + Arrays.toString(byRegion) +
            ", stuEventHandler=" + stuEventHandler +
            ", stuTimeSection=" + Arrays.toString(stuTimeSection) +
            ", nVersion=" + nVersion +
            ", bSenseLevelEn=" + bSenseLevelEn +
            ", bVRatioEn=" + bVRatioEn +
            ", nVolumeRatio=" + nVolumeRatio +
            ", bSRatioEn=" + bSRatioEn +
            ", nSubRatio=" + nSubRatio +
            ", abWindow=" + abWindow +
            ", nWindowCount=" + nWindowCount +
            ", stuWindows=" + Arrays.toString(stuWindows) +
            ", abDetectRegion=" + abDetectRegion +
            ", nRegionCount=" + nRegionCount +
            ", stuRegion=" + Arrays.toString(stuRegion) +
            ", stuRemoteEventHandler=" + stuRemoteEventHandler +
            ", stuRemoteTimeSection=" + Arrays.toString(stuRemoteTimeSection) +
            '}';
  }
      public  CFG_MOTION_INFO(){
            for(int i=0;i<byRegion.length;i++){
              byRegion[i]=new BYTE_32();
            }
            for(int i=0;i<stuTimeSection.length;i++){
              stuTimeSection[i]=new  NetSDKLib.CFG_TIME_SECTION();
            }
            for(int i=0;i<stuWindows.length;i++){
              stuWindows[i]=new CFG_MOTION_WINDOW();
            }
            for(int i=0;i<stuRegion.length;i++){
              stuRegion[i]= new  CFG_DETECT_REGION();
            }
            for(int i=0;i<stuRemoteTimeSection.length;i++){
              stuRemoteTimeSection[i]=new NetSDKLib.CFG_TIME_SECTION();
            }
      }
}
package com.ruoyi.device.dhsdk.lib.structure;
/**
 * @author 47081
 * @desc
 * @version 1.0.0
 * @date 2021/4/9
 */
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.sun.jna.ptr.IntByReference;
import java.util.Arrays;
import static com.ruoyi.device.dhsdk.lib.NetSDKLib.MAX_REC_TSECT;
import static com.ruoyi.device.dhsdk.lib.constant.SDKStructureFieldLenth.*;
/**
 * @author 47081
 * @description 动态监测报警配置,对应接口 {@link
 *     com.ruoyi.device.dhsdk.lib.NetSDKLib#CLIENT_GetNewDevConfig(NetSDKLib.LLong, String, int, byte[], int,
 *     IntByReference, int)}和{@link NetSDKLib#CLIENT_SetNewDevConfig(NetSDKLib.LLong, String, int,
 *     byte[], int, IntByReference, IntByReference, int)}
 * @date 2021/4/9
 * @version 1.0
 */
public class CFG_MOTION_INFO extends NetSDKLib.SdkStructure {
  /** 报警通道号(0开始), nVersion=1时,此字段无效 */
  public int nChannelID;
  /** 使能开关 */
  public int bEnable;
  /** 一代动检灵敏度1~6 */
  public int nSenseLevel;
  /** 一代动态检测区域的行数 */
  public int nMotionRow;
  /** 一代动态检测区域的列数 */
  public int nMotionCol;
  /** 一代检测区域,最多32*32块区域 */
  public BYTE_32[] byRegion = new BYTE_32[MAX_MOTION_ROW];
  /** 报警联动 */
  public NetSDKLib.CFG_ALARM_MSG_HANDLE stuEventHandler=new NetSDKLib.CFG_ALARM_MSG_HANDLE();
  /** 事件响应时间段,时间段获取和设置以此成员为准,忽略 stuEventHandler 中的stuTimeSection */
  public NetSDKLib.CFG_TIME_SECTION[] stuTimeSection =
          new NetSDKLib.CFG_TIME_SECTION[WEEK_DAY_NUM * MAX_REC_TSECT];
  /** 0, 1, 由能力集确定, 只读, 等于1时以下字段有效 */
  public int nVersion;
  /** 只读,决定nSenseLevel是否有效 */
  public int bSenseLevelEn;
  /** 只读,面积占用比使能, 决定nVolumeRatio是否有效 */
  public int bVRatioEn;
  /** 一代动检的面积占用比,1-100 */
  public int nVolumeRatio;
  /** 只读,灵敏度使能,决定nSubRatio值是否有效 */
  public int bSRatioEn;
  /** 一代动检的残差阈值, 1-100 */
  public int nSubRatio;
  /** 此字段及以下两个字段已废弃 */
  public int abWindow;
  /** 视频窗口个数 */
  @Deprecated public int nWindowCount;
  /** 视频窗口数组 */
  @Deprecated
  public CFG_MOTION_WINDOW[] stuWindows = new CFG_MOTION_WINDOW[MAX_MOTION_WINDOW];
  /** 只读, 1:nRegionCount,stuRegion有效 0:nMotionRow,nMotionCol,byRegion有效 */
  public int abDetectRegion;
  /** 三代动态检测区域个数 */
  public int nRegionCount;
  /** 三代动态检测区域 */
  public CFG_DETECT_REGION[] stuRegion =
    new CFG_DETECT_REGION[MAX_MOTION_WINDOW];
  /** 前端动态检测联动 */
  public NetSDKLib.CFG_ALARM_MSG_HANDLE stuRemoteEventHandler=new NetSDKLib.CFG_ALARM_MSG_HANDLE();
  /** 前端动态检测联动, 事件响应时间段,时间段获取和设置以此成员为准,忽略 stuRemoteEventHandler中的stuTimeSection */
  public NetSDKLib.CFG_TIME_SECTION[] stuRemoteTimeSection =
          new NetSDKLib.CFG_TIME_SECTION[WEEK_DAY_NUM * MAX_REC_TSECT];
  @Override
  public String toString() {
    return "CFG_MOTION_INFO{" +
            "nChannelID=" + nChannelID +
            ", bEnable=" + bEnable +
            ", nSenseLevel=" + nSenseLevel +
            ", nMotionRow=" + nMotionRow +
            ", nMotionCol=" + nMotionCol +
            ", byRegion=" + Arrays.toString(byRegion) +
            ", stuEventHandler=" + stuEventHandler +
            ", stuTimeSection=" + Arrays.toString(stuTimeSection) +
            ", nVersion=" + nVersion +
            ", bSenseLevelEn=" + bSenseLevelEn +
            ", bVRatioEn=" + bVRatioEn +
            ", nVolumeRatio=" + nVolumeRatio +
            ", bSRatioEn=" + bSRatioEn +
            ", nSubRatio=" + nSubRatio +
            ", abWindow=" + abWindow +
            ", nWindowCount=" + nWindowCount +
            ", stuWindows=" + Arrays.toString(stuWindows) +
            ", abDetectRegion=" + abDetectRegion +
            ", nRegionCount=" + nRegionCount +
            ", stuRegion=" + Arrays.toString(stuRegion) +
            ", stuRemoteEventHandler=" + stuRemoteEventHandler +
            ", stuRemoteTimeSection=" + Arrays.toString(stuRemoteTimeSection) +
            '}';
  }
      public  CFG_MOTION_INFO(){
            for(int i=0;i<byRegion.length;i++){
              byRegion[i]=new BYTE_32();
            }
            for(int i=0;i<stuTimeSection.length;i++){
              stuTimeSection[i]=new  NetSDKLib.CFG_TIME_SECTION();
            }
            for(int i=0;i<stuWindows.length;i++){
              stuWindows[i]=new CFG_MOTION_WINDOW();
            }
            for(int i=0;i<stuRegion.length;i++){
              stuRegion[i]= new  CFG_DETECT_REGION();
            }
            for(int i=0;i<stuRemoteTimeSection.length;i++){
              stuRemoteTimeSection[i]=new NetSDKLib.CFG_TIME_SECTION();
            }
      }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_ALARM_DEVICE_MODIFIED_INFO.java
@@ -1,25 +1,25 @@
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
/**
 * @author 291189
 * @version 1.0
 * @description 设备设息修改(增加、删除、修改)报警上报事件 (对应 NET_ALARM_DEVICE_MODIFIED)
 * @date 2022/7/19 11:17
 */
public class NET_ALARM_DEVICE_MODIFIED_INFO extends NetSDKLib.SdkStructure{
    public  int                                    nAction;         // 事件动作 0:脉冲
    public    int                                 nChannel;        // 通道号
    public    NET_TIME_EX                            stuUTC=new NET_TIME_EX();          // 事件发生的时间,标准的(不带时区偏差的)UTC时间
    public    byte[]                                szUser=new byte[32];     // 用户名称
    /**
     * {@link  com.netsdk.lib.enumeration.NET_EVENT_OPERATE_TYPE}
     */
    public  int emOpType;        // 操作类型
    /**
     * {@link  com.netsdk.lib.enumeration.NET_EVENT_DEVICE_TYPE}
     */
    public  int emDeviceType;    // 设备类型
    public byte[]                    szReserved=new byte[1024];// 保留字节
}
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
/**
 * @author 291189
 * @version 1.0
 * @description 设备设息修改(增加、删除、修改)报警上报事件 (对应 NET_ALARM_DEVICE_MODIFIED)
 * @date 2022/7/19 11:17
 */
public class NET_ALARM_DEVICE_MODIFIED_INFO extends NetSDKLib.SdkStructure{
    public  int                                    nAction;         // 事件动作 0:脉冲
    public    int                                 nChannel;        // 通道号
    public    NET_TIME_EX                            stuUTC=new NET_TIME_EX();          // 事件发生的时间,标准的(不带时区偏差的)UTC时间
    public    byte[]                                szUser=new byte[32];     // 用户名称
    /**
     * {@link  com.ruoyi.device.dhsdk.lib.enumeration.NET_EVENT_OPERATE_TYPE}
     */
    public  int emOpType;        // 操作类型
    /**
     * {@link  com.ruoyi.device.dhsdk.lib.enumeration.NET_EVENT_DEVICE_TYPE}
     */
    public  int emDeviceType;    // 设备类型
    public byte[]                    szReserved=new byte[1024];// 保留字节
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO.java
@@ -1,44 +1,44 @@
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import java.util.Arrays;
/**
 * @author 47081
 * @version 1.0
 * @description 门禁假日组配置,对应枚举 {@link
 *     com.netsdk.lib.enumeration.NET_EM_CFG_OPERATE_TYPE#NET_EM_CFG_ACCESSCTL_SPECIALDAY_GROUP}
 * @date 2020/10/19
 */
public class NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO extends NetSDKLib.SdkStructure {
  public int dwSize;
  /** 组使能 */
  public boolean bGroupEnable;
  /** 组名称 */
  public byte[] szGroupName = new byte[32];
  /** 有效的节假日数量 */
  public int nSpeciaday;
  /** 假日信息 */
  public NET_ACCESSCTL_SPECIALDAY_INFO[] stuSpeciaday =
      (NET_ACCESSCTL_SPECIALDAY_INFO[]) new NET_ACCESSCTL_SPECIALDAY_INFO().toArray(16);
  public NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO() {
    this.dwSize = this.size();
  }
  @Override
  public String toString() {
    return "假日组,NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO{"
        + "bGroupEnable="
        + bGroupEnable
        + ", szGroupName="
        + new String(szGroupName).trim()
        + ", nSpeciaday="
        + nSpeciaday
        + ", stuSpeciaday="
        + Arrays.toString(stuSpeciaday)
        + '}';
  }
}
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import java.util.Arrays;
/**
 * @author 47081
 * @version 1.0
 * @description 门禁假日组配置,对应枚举 {@link
 *     com.ruoyi.device.dhsdk.lib.enumeration.NET_EM_CFG_OPERATE_TYPE#NET_EM_CFG_ACCESSCTL_SPECIALDAY_GROUP}
 * @date 2020/10/19
 */
public class NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO extends NetSDKLib.SdkStructure {
  public int dwSize;
  /** 组使能 */
  public boolean bGroupEnable;
  /** 组名称 */
  public byte[] szGroupName = new byte[32];
  /** 有效的节假日数量 */
  public int nSpeciaday;
  /** 假日信息 */
  public NET_ACCESSCTL_SPECIALDAY_INFO[] stuSpeciaday =
      (NET_ACCESSCTL_SPECIALDAY_INFO[]) new NET_ACCESSCTL_SPECIALDAY_INFO().toArray(16);
  public NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO() {
    this.dwSize = this.size();
  }
  @Override
  public String toString() {
    return "假日组,NET_CFG_ACCESSCTL_SPECIALDAY_GROUP_INFO{"
        + "bGroupEnable="
        + bGroupEnable
        + ", szGroupName="
        + new String(szGroupName).trim()
        + ", nSpeciaday="
        + nSpeciaday
        + ", stuSpeciaday="
        + Arrays.toString(stuSpeciaday)
        + '}';
  }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_IN_PERSON_INFO_INPUT_RESULT.java
@@ -1,42 +1,42 @@
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
/**
 * CLIENT_SetPersonInfoInputResult 输入参数
 */
public class NET_IN_PERSON_INFO_INPUT_RESULT extends NetSDKLib.SdkStructure {
    /**
     * 结构体大小
     */
    public int dwSize;
    /**
     * 通道ID
     */
    public int nChannelID;
    /**
     * 0 : 成功 1 : 人员信息不在人员库中
     */
    public int nResult;
    /**
     * 字节对齐
     */
    public byte[] byReserved = new byte[4];
    /**
     * 证件号码
     */
    public byte[] szCitizenID = new byte[64];
    /**
     * 设备展示颜色 com.netsdk.lib.enumeration.EM_SHOW_COLOR
     */
    public int emColor;
    /**
     * 0:实时采集的数据 1:离线采集的数据
     */
    public int nDataType;
    public NET_IN_PERSON_INFO_INPUT_RESULT() {
        this.dwSize = this.size();
    }
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
/**
 * CLIENT_SetPersonInfoInputResult 输入参数
 */
public class NET_IN_PERSON_INFO_INPUT_RESULT extends NetSDKLib.SdkStructure {
    /**
     * 结构体大小
     */
    public int dwSize;
    /**
     * 通道ID
     */
    public int nChannelID;
    /**
     * 0 : 成功 1 : 人员信息不在人员库中
     */
    public int nResult;
    /**
     * 字节对齐
     */
    public byte[] byReserved = new byte[4];
    /**
     * 证件号码
     */
    public byte[] szCitizenID = new byte[64];
    /**
     * 设备展示颜色 com.ruoyi.device.dhsdk.lib.enumeration.EM_SHOW_COLOR
     */
    public int emColor;
    /**
     * 0:实时采集的数据 1:离线采集的数据
     */
    public int nDataType;
    public NET_IN_PERSON_INFO_INPUT_RESULT() {
        this.dwSize = this.size();
    }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/NET_IN_START_REDIRECT_SERVICE.java
@@ -1,43 +1,43 @@
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.callback.fRedirectServerCallBackEx;
import com.sun.jna.Callback;
import com.sun.jna.Pointer;
/**
 * @author 47081
 * @version 1.0
 * @description CLIENT_StartRedirectServiceEx接口输入参数, {@link
 *     com.netsdk.lib.NetSDKLib#CLIENT_StartRedirectServiceEx(Pointer, Pointer)}
 * @date 2021/3/13
 */
public class NET_IN_START_REDIRECT_SERVICE extends NetSDKLib.SdkStructure {
  /** 结构体大小, 需要赋值为当前结构体所在大小 */
  public int dwSize;
  /** 预留字节 */
  public byte[] byReserved = new byte[4];
  /** 主动注册重定向服务器IP */
  public byte[] szIP = new byte[64];
  /** 主动注册重定向服务器端口 */
  public short nPort;
  /** 预留字节 */
  public byte[] byReserved1 = new byte[6];
  /** 设备重定向回调函数(扩展) */
  public fRedirectServerCallBackEx cbFuncEx;
  /** 用户参数, 与fRedirectServerCallBackEx绑定 */
  public Pointer dwUserData;
  /**
   * DWORD dwSize; // 结构体大小, 需要赋值为当前结构体所在大小
   * BYTE byReserved[4]; // 预留字节
   * char szIP[64]; //
   * 主动注册重定向服务器IP WORD nPort; // 主动注册重定向服务器端口
   * BYTE byReserved1[6]; // 预留字节
   * fRedirectServerCallBackEx
   * cbFuncEx; // 设备重定向回调函数(扩展) LDWORD dwUserData; // 用户参数, 与fRedirectServerCallBackEx绑定
   */
  public NET_IN_START_REDIRECT_SERVICE() {
    this.dwSize = this.size();
  }
}
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.callback.fRedirectServerCallBackEx;
import com.sun.jna.Callback;
import com.sun.jna.Pointer;
/**
 * @author 47081
 * @version 1.0
 * @description CLIENT_StartRedirectServiceEx接口输入参数, {@link
 *     com.ruoyi.device.dhsdk.lib.NetSDKLib#CLIENT_StartRedirectServiceEx(Pointer, Pointer)}
 * @date 2021/3/13
 */
public class NET_IN_START_REDIRECT_SERVICE extends NetSDKLib.SdkStructure {
  /** 结构体大小, 需要赋值为当前结构体所在大小 */
  public int dwSize;
  /** 预留字节 */
  public byte[] byReserved = new byte[4];
  /** 主动注册重定向服务器IP */
  public byte[] szIP = new byte[64];
  /** 主动注册重定向服务器端口 */
  public short nPort;
  /** 预留字节 */
  public byte[] byReserved1 = new byte[6];
  /** 设备重定向回调函数(扩展) */
  public fRedirectServerCallBackEx cbFuncEx;
  /** 用户参数, 与fRedirectServerCallBackEx绑定 */
  public Pointer dwUserData;
  /**
   * DWORD dwSize; // 结构体大小, 需要赋值为当前结构体所在大小
   * BYTE byReserved[4]; // 预留字节
   * char szIP[64]; //
   * 主动注册重定向服务器IP WORD nPort; // 主动注册重定向服务器端口
   * BYTE byReserved1[6]; // 预留字节
   * fRedirectServerCallBackEx
   * cbFuncEx; // 设备重定向回调函数(扩展) LDWORD dwUserData; // 用户参数, 与fRedirectServerCallBackEx绑定
   */
  public NET_IN_START_REDIRECT_SERVICE() {
    this.dwSize = this.size();
  }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/UNPACKING_CHECK_INFO.java
@@ -1,89 +1,89 @@
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
/**
 * @author 291189
 * @version 1.0
 * @description 开包检查信息
 * @date 2021/9/9
 */
public class UNPACKING_CHECK_INFO extends NetSDKLib.SdkStructure {
    /**
     * 事件发生时间,带时区偏差的UTC时间,单位秒
     */
    public int nUTC;
    /**
     * 事件时间毫秒数
     */
    public int nUTCMS;
    /**
     * 表示包裹标识,用来唯一标识一个包裹
     */
    public byte[] szPackageTag = new byte[32];
    /**
     * 关联图片
     */
    public RELATED_IMAGE[] stuRelatedImage = new RELATED_IMAGE[64];
    /**
     * 关联图片数量
     */
    public int nRelatedImageRetNum;
    /**
     * 报警时间(即拍摄违禁品时间),UTC时间,单位秒
     */
    public int nAlarmTime;
    /**
     * 身份信息
     */
    public IDENTITY_INFO stuIdentityInfo = new IDENTITY_INFO();
    /**
     * 违禁物品分类 已经废弃
     */
    public OneDimensionalInformation[] szContrabandClass = new OneDimensionalInformation[16];
    /**
     * 违禁物品个数
     */
    public int nContrabandRetNum;
    /**
     * 处理方式  EM_PROCESS_MODE
     */
    public int emProcessMode;
    /**
     * 检出人,即开包人员
     */
    public byte[] szChecker = new byte[128];
    /**
     * 报警地点
     */
    public byte[] szAlarmLocation = new byte[256];
    /**
     * com.netsdk.lib.NetSDKLib.EM_INSIDE_OBJECT_TYPE
     */
    public int[] emContrabandClass = new int[64];           // 违禁物品分类
    /**
     * 行程出发地
     */
    public byte[] szPlaceOfDeparture = new byte[256];
    /**
     * 行程目的地
     */
    public byte[] szDestination = new byte[256];
    /**
     * 预留字节
     */
    public byte[] szReserved = new byte[18688];
    public UNPACKING_CHECK_INFO() {
        for (int i = 0; i < 16; i++) {
            szContrabandClass[i] = new OneDimensionalInformation();
        }
        for (int i = 0; i < 64; i++) {
            stuRelatedImage[i] = new RELATED_IMAGE();
        }
    }
package com.ruoyi.device.dhsdk.lib.structure;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
/**
 * @author 291189
 * @version 1.0
 * @description 开包检查信息
 * @date 2021/9/9
 */
public class UNPACKING_CHECK_INFO extends NetSDKLib.SdkStructure {
    /**
     * 事件发生时间,带时区偏差的UTC时间,单位秒
     */
    public int nUTC;
    /**
     * 事件时间毫秒数
     */
    public int nUTCMS;
    /**
     * 表示包裹标识,用来唯一标识一个包裹
     */
    public byte[] szPackageTag = new byte[32];
    /**
     * 关联图片
     */
    public RELATED_IMAGE[] stuRelatedImage = new RELATED_IMAGE[64];
    /**
     * 关联图片数量
     */
    public int nRelatedImageRetNum;
    /**
     * 报警时间(即拍摄违禁品时间),UTC时间,单位秒
     */
    public int nAlarmTime;
    /**
     * 身份信息
     */
    public IDENTITY_INFO stuIdentityInfo = new IDENTITY_INFO();
    /**
     * 违禁物品分类 已经废弃
     */
    public OneDimensionalInformation[] szContrabandClass = new OneDimensionalInformation[16];
    /**
     * 违禁物品个数
     */
    public int nContrabandRetNum;
    /**
     * 处理方式  EM_PROCESS_MODE
     */
    public int emProcessMode;
    /**
     * 检出人,即开包人员
     */
    public byte[] szChecker = new byte[128];
    /**
     * 报警地点
     */
    public byte[] szAlarmLocation = new byte[256];
    /**
     * com.ruoyi.device.dhsdk.lib.NetSDKLib.EM_INSIDE_OBJECT_TYPE
     */
    public int[] emContrabandClass = new int[64];           // 违禁物品分类
    /**
     * 行程出发地
     */
    public byte[] szPlaceOfDeparture = new byte[256];
    /**
     * 行程目的地
     */
    public byte[] szDestination = new byte[256];
    /**
     * 预留字节
     */
    public byte[] szReserved = new byte[18688];
    public UNPACKING_CHECK_INFO() {
        for (int i = 0; i < 16; i++) {
            szContrabandClass[i] = new OneDimensionalInformation();
        }
        for (int i = 0; i < 64; i++) {
            stuRelatedImage[i] = new RELATED_IMAGE();
        }
    }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/CANDIDATE_INFO_CEX.java
@@ -1,67 +1,67 @@
package com.netsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.Utils;
import com.ruoyi.device.dhsdk.lib.structure.NET_TIME;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
 * @author 47081
 * @version 1.0
 * @description 候选人信息拓展结构体(),结构体, 日常使用以structure包和NetSDKLib下的同名结构体为主
 * @date 2021/3/17
 */
public class CANDIDATE_INFO_CEX extends NetSDKLib.SdkStructure {
  /** 姓名 */
  public byte[] szPersonName = new byte[64];
  /** 人员唯一标示(证件号码,工号,或其他编号) */
  public byte[] szID = new byte[32];
  /** 和查询图片的相似度,百分比表示,1~100 */
  public byte bySimilarity;
  /** 人员所属数据库范围,详见EM_FACE_DB_TYPE */
  public byte byRange;
  /** 当byRange为历史数据库时有效,表示查询人员出现的时间 */
  public NET_TIME stTime;
  /** 当byRange为历史数据库时有效,表示查询人员出现的地点 */
  public byte[] szAddress = new byte[260];
  /** 是否有识别结果,指这个检测出的人脸在库中有没有比对结果 */
  public boolean bIsHit;
  /** 通道号 */
  public int nChannelID;
  public String getPersonName() {
    return new String(szPersonName, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  public String getID() {
    return new String(szID, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  public String getAddress() {
    return new String(szAddress, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  @Override
  public String toString() {
    return "CANDIDATE_INFO_CEX{"
        + "szPersonName="
        + getPersonName()
        + ", szID="
        + getID()
        + ", bySimilarity="
        + bySimilarity
        + ", byRange="
        + byRange
        + ", stTime="
        + stTime
        + ", szAddress="
        + getAddress()
        + ", bIsHit="
        + bIsHit
        + ", nChannelID="
        + nChannelID
        + '}';
  }
}
package com.ruoyi.device.dhsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.Utils;
import com.ruoyi.device.dhsdk.lib.structure.NET_TIME;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
 * @author 47081
 * @version 1.0
 * @description 候选人信息拓展结构体(),结构体, 日常使用以structure包和NetSDKLib下的同名结构体为主
 * @date 2021/3/17
 */
public class CANDIDATE_INFO_CEX extends NetSDKLib.SdkStructure {
  /** 姓名 */
  public byte[] szPersonName = new byte[64];
  /** 人员唯一标示(证件号码,工号,或其他编号) */
  public byte[] szID = new byte[32];
  /** 和查询图片的相似度,百分比表示,1~100 */
  public byte bySimilarity;
  /** 人员所属数据库范围,详见EM_FACE_DB_TYPE */
  public byte byRange;
  /** 当byRange为历史数据库时有效,表示查询人员出现的时间 */
  public NET_TIME stTime;
  /** 当byRange为历史数据库时有效,表示查询人员出现的地点 */
  public byte[] szAddress = new byte[260];
  /** 是否有识别结果,指这个检测出的人脸在库中有没有比对结果 */
  public boolean bIsHit;
  /** 通道号 */
  public int nChannelID;
  public String getPersonName() {
    return new String(szPersonName, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  public String getID() {
    return new String(szID, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  public String getAddress() {
    return new String(szAddress, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  @Override
  public String toString() {
    return "CANDIDATE_INFO_CEX{"
        + "szPersonName="
        + getPersonName()
        + ", szID="
        + getID()
        + ", bySimilarity="
        + bySimilarity
        + ", byRange="
        + byRange
        + ", stTime="
        + stTime
        + ", szAddress="
        + getAddress()
        + ", bIsHit="
        + bIsHit
        + ", nChannelID="
        + nChannelID
        + '}';
  }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/DEV_EVENT_CROSSLINE_INFO.java
@@ -1,158 +1,158 @@
package com.netsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import static com.ruoyi.device.dhsdk.lib.NetSDKLib.*;
/**
 * 船只绊线入侵事件结构体
 * <p>
 * ERR210428143 水面预警事件 专用结构体
 * <p>
 * 注意: 其他项目不要使用, 通用的停车检测事件结构体见:
 * {@link NetSDKLib.DEV_EVENT_CROSSLINE_INFO}
 *
 * @author 47040
 * @since Created in 2021/5/13 19:03
 */
public class DEV_EVENT_CROSSLINE_INFO extends SdkStructure {
    /**
     * 通道号
     */
    public int nChannelID;
    /**
     * 事件名称
     */
    public byte[] szName = new byte[128];
    /**
     * 字节对齐
     */
    public byte[] bReserved1 = new byte[4];
    /**
     * 时间戳(单位是毫秒)
     */
    public double PTS;
    /**
     * 事件发生的时间
     */
    public NET_TIME_EX UTC;
    /**
     * 事件ID
     */
    public int nEventID;
    /**
     * 检测到的物体
     */
    public NET_MSG_OBJECT stuObject;
    /**
     * 事件对应文件信息
     */
    public NET_EVENT_FILE_INFO stuFileInfo;
    /**
     * 规则检测线
     */
    public NET_POINT[] DetectLine = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_DETECT_LINE_NUM);
    /**
     * 规则检测线顶点数
     */
    public int nDetectLineNum;
    /**
     * 物体运动轨迹
     */
    public NET_POINT[] TrackLine = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_TRACK_LINE_NUM);
    /**
     * 物体运动轨迹顶点数
     */
    public int nTrackLineNum;
    /**
     * 事件动作,0表示脉冲事件,1表示持续性事件开始,2表示持续性事件结束;
     */
    public byte bEventAction;
    /**
     * 表示入侵方向, 0-由左至右, 1-由右至左
     */
    public byte bDirection;
    /**
     * 字节对齐
     */
    public byte[] byReserved = new byte[1];
    /**
     * 图片的序号, 同一时间内(精确到秒)可能有多张图片, 从0开始
     */
    public byte byImageIndex;
    /**
     * 抓图标志(按位),具体见  NET_RESERVED_COMMON,
     * 0位:"*",1位:"Timing",2位:"Manual",
     * 3位:"Marked",4位:"Event",5位:"Mosaic",6位:"Cutout"
     */
    public int dwSnapFlagMask;
    /**
     * 事件源设备上的index,-1表示数据无效,-1表示数据无效
     */
    public int nSourceIndex;
    /**
     * 事件源设备唯一标识,字段不存在或者为空表示本地设备
     */
    public byte[] szSourceDevice = new byte[MAX_PATH];
    /**
     * 事件触发累计次数, 类型为unsigned int
     */
    public int nOccurrenceCount;
    /**
     * 智能事件公共信息
     */
    public EVENT_INTELLI_COMM_INFO stuIntelliCommInfo;
    /**
     * 扩展信息
     */
    public NET_EXTENSION_INFO stuExtensionInfo;
    /**
     * 全景广角图
     */
    public SCENE_IMAGE_INFO_EX stuSceneImage;
    /**
     * 检测到人的数量
     */
    public int nObjetcHumansNum;
    /**
     * 检测的到人
     */
    public NET_VAOBJECT_NUMMAN[] stuObjetcHumans = (NET_VAOBJECT_NUMMAN[]) new NET_VAOBJECT_NUMMAN().toArray(100);
    /**
     * 规则编号,用于标示哪个规则触发的事件,缺省时默认为0
     */
    public int nRuleID;
    /**
     * 事件级别 {@link EM_EVENT_LEVEL}
     */
    public int emEventType;
    /**
     * 热成像横向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoHFOV;
    /**
     * 热成像纵向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoVFOV;
    /**
     * 船高 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatHeight;
    /**
     * 船长 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatLength;
    /**
     * 船速 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatSpeed;
    /**
     * 船距 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatDistance;
    /**
     * 字节对齐
     */
    public byte[] byReserved1 = new byte[480];
}
package com.ruoyi.device.dhsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import static com.ruoyi.device.dhsdk.lib.NetSDKLib.*;
/**
 * 船只绊线入侵事件结构体
 * <p>
 * ERR210428143 水面预警事件 专用结构体
 * <p>
 * 注意: 其他项目不要使用, 通用的停车检测事件结构体见:
 * {@link NetSDKLib.DEV_EVENT_CROSSLINE_INFO}
 *
 * @author 47040
 * @since Created in 2021/5/13 19:03
 */
public class DEV_EVENT_CROSSLINE_INFO extends SdkStructure {
    /**
     * 通道号
     */
    public int nChannelID;
    /**
     * 事件名称
     */
    public byte[] szName = new byte[128];
    /**
     * 字节对齐
     */
    public byte[] bReserved1 = new byte[4];
    /**
     * 时间戳(单位是毫秒)
     */
    public double PTS;
    /**
     * 事件发生的时间
     */
    public NET_TIME_EX UTC;
    /**
     * 事件ID
     */
    public int nEventID;
    /**
     * 检测到的物体
     */
    public NET_MSG_OBJECT stuObject;
    /**
     * 事件对应文件信息
     */
    public NET_EVENT_FILE_INFO stuFileInfo;
    /**
     * 规则检测线
     */
    public NET_POINT[] DetectLine = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_DETECT_LINE_NUM);
    /**
     * 规则检测线顶点数
     */
    public int nDetectLineNum;
    /**
     * 物体运动轨迹
     */
    public NET_POINT[] TrackLine = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_TRACK_LINE_NUM);
    /**
     * 物体运动轨迹顶点数
     */
    public int nTrackLineNum;
    /**
     * 事件动作,0表示脉冲事件,1表示持续性事件开始,2表示持续性事件结束;
     */
    public byte bEventAction;
    /**
     * 表示入侵方向, 0-由左至右, 1-由右至左
     */
    public byte bDirection;
    /**
     * 字节对齐
     */
    public byte[] byReserved = new byte[1];
    /**
     * 图片的序号, 同一时间内(精确到秒)可能有多张图片, 从0开始
     */
    public byte byImageIndex;
    /**
     * 抓图标志(按位),具体见  NET_RESERVED_COMMON,
     * 0位:"*",1位:"Timing",2位:"Manual",
     * 3位:"Marked",4位:"Event",5位:"Mosaic",6位:"Cutout"
     */
    public int dwSnapFlagMask;
    /**
     * 事件源设备上的index,-1表示数据无效,-1表示数据无效
     */
    public int nSourceIndex;
    /**
     * 事件源设备唯一标识,字段不存在或者为空表示本地设备
     */
    public byte[] szSourceDevice = new byte[MAX_PATH];
    /**
     * 事件触发累计次数, 类型为unsigned int
     */
    public int nOccurrenceCount;
    /**
     * 智能事件公共信息
     */
    public EVENT_INTELLI_COMM_INFO stuIntelliCommInfo;
    /**
     * 扩展信息
     */
    public NET_EXTENSION_INFO stuExtensionInfo;
    /**
     * 全景广角图
     */
    public SCENE_IMAGE_INFO_EX stuSceneImage;
    /**
     * 检测到人的数量
     */
    public int nObjetcHumansNum;
    /**
     * 检测的到人
     */
    public NET_VAOBJECT_NUMMAN[] stuObjetcHumans = (NET_VAOBJECT_NUMMAN[]) new NET_VAOBJECT_NUMMAN().toArray(100);
    /**
     * 规则编号,用于标示哪个规则触发的事件,缺省时默认为0
     */
    public int nRuleID;
    /**
     * 事件级别 {@link EM_EVENT_LEVEL}
     */
    public int emEventType;
    /**
     * 热成像横向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoHFOV;
    /**
     * 热成像纵向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoVFOV;
    /**
     * 船高 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatHeight;
    /**
     * 船长 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatLength;
    /**
     * 船速 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatSpeed;
    /**
     * 船距 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatDistance;
    /**
     * 字节对齐
     */
    public byte[] byReserved1 = new byte[480];
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/DEV_EVENT_CROSSREGION_INFO.java
@@ -1,209 +1,209 @@
package com.netsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.enumeration.EM_CAPTURE_PROCESS_END_TYPE;
import com.ruoyi.device.dhsdk.lib.enumeration.EM_TRIGGER_TYPE;
import static com.ruoyi.device.dhsdk.lib.NetSDKLib.*;
/**
 * 船只的绊线入侵事件信息
 * <p>
 * ERR210428143 水面预警事件 专用结构体
 * <p>
 * 注意: 其他项目不要使用, 通用的绊线入侵事件结构体见:
 * {@link NetSDKLib.DEV_EVENT_CROSSREGION_INFO}
 *
 * @author 47040
 * @since Created in 2021/5/13 17:35
 */
public class DEV_EVENT_CROSSREGION_INFO extends SdkStructure {
    /**
     * 通道号
     */
    public int nChannelID;
    /**
     * 事件名称
     */
    public byte[] szName = new byte[128];
    /**
     * 字节对齐
     */
    public byte[] bReserved1 = new byte[4];
    /**
     * 时间戳(单位是毫秒)
     */
    public double PTS;
    /**
     * 事件发生的时间
     */
    public NET_TIME_EX UTC;
    /**
     * 事件ID
     */
    public int nEventID;
    /**
     * 检测到的物体
     */
    public NET_MSG_OBJECT stuObject;
    /**
     * 事件对应文件信息
     */
    public NET_EVENT_FILE_INFO stuFileInfo;
    /**
     * 规则检测区域
     */
    public NET_POINT[] DetectRegion = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_DETECT_REGION_NUM);
    /**
     * 规则检测区域顶点数
     */
    public int nDetectRegionNum;
    /**
     * 物体运动轨迹
     */
    public NET_POINT[] TrackLine = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_TRACK_LINE_NUM);
    /**
     * 物体运动轨迹顶点数
     */
    public int nTrackLineNum;
    /**
     * 事件动作,0表示脉冲事件,1表示持续性事件开始,2表示持续性事件结束;
     */
    public byte bEventAction;
    /**
     * 表示入侵方向, 0-进入, 1-离开,2-出现,3-消失
     */
    public byte bDirection;
    /**
     * 表示检测动作类型,0-出现 1-消失 2-在区域内 3-穿越区域
     */
    public byte bActionType;
    /**
     * 图片的序号, 同一时间内(精确到秒)可能有多张图片, 从0开始
     */
    public byte byImageIndex;
    /**
     * 抓图标志(按位),具体见NET_RESERVED_COMMON ,
     * 0位:"*",1位:"Timing",2位:"Manual",
     * 3位:"Marked",4位:"Event",5位:"Mosaic",6位:"Cutout"
     */
    public int dwSnapFlagMask;
    /**
     * 事件源设备上的index,-1表示数据无效
     */
    public int nSourceIndex;
    /**
     * 事件源设备唯一标识,字段不存在或者为空表示本地设备
     */
    public byte[] szSourceDevice = new byte[MAX_PATH];
    /**
     * 事件触发累计次数, int 类型
     */
    public int nOccurrenceCount;
    /**
     * 货物通道信息
     */
    public NET_CUSTOM_INFO stuCustom;
    /**
     * 扩展信息
     */
    public NET_EXTENSION_INFO stuExtensionInfo;
    /**
     * 智能事件规则编号,用于标示哪个规则触发的事件
     */
    public int nRuleID;
    /**
     * 热成像横向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoHFOV;
    /**
     * 热成像纵向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoVFOV;
    /**
     * 船高 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatHeight;
    /**
     * 船长 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatLength;
    /**
     * 船速 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatSpeed;
    /**
     * 船距 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatDistance;
    /**
     * 保留字节,留待扩展.
     */
    public byte[] bReserved = new byte[300];
    /**
     * 检测到的物体个数
     */
    public int nObjectNum;
    /**
     * 检测到的物体
     */
    public NET_MSG_OBJECT[] stuObjectIDs = (NET_MSG_OBJECT[]) new NET_MSG_OBJECT().toArray(NET_MAX_OBJECT_LIST);
    /**
     * 轨迹数(与检测到的物体个数  nObjectNum 对应)
     */
    public int nTrackNum;
    /**
     * 轨迹信息(与检测到的物体对应)
     */
    public NET_POLY_POINTS[] stuTrackInfo = (NET_POLY_POINTS[]) new NET_POLY_POINTS().toArray(NET_MAX_OBJECT_LIST);
    /**
     * 智能事件公共信息
     */
    public EVENT_INTELLI_COMM_INFO stuIntelliCommInfo;
    /**
     * 全景广角图
     */
    public SCENE_IMAGE_INFO_EX stuSceneImage;
    /**
     * 检测到人的数量
     */
    public int nObjetcHumansNum;
    /**
     * 检测的到人
     */
    public NET_VAOBJECT_NUMMAN[] stuObjetcHumans = (NET_VAOBJECT_NUMMAN[]) new NET_VAOBJECT_NUMMAN().toArray(100);
    /**
     * 车身信息
     */
    public NET_MSG_OBJECT stuVehicle;
    /**
     * 触发类型,参考 {@link EM_TRIGGER_TYPE}
     */
    public int emTriggerType;
    /**
     * 标记抓拍帧
     */
    public int nMark;
    /**
     * 视频分析的数据源地址
     */
    public int nSource;
    /**
     * 视频分析帧序号
     */
    public int nFrameSequence;
    /**
     * 抓拍过程,参考 {@link EM_CAPTURE_PROCESS_END_TYPE}
     */
    public int emCaptureProcess;
    /**
     * 交通车辆信息
     */
    public DEV_EVENT_TRAFFIC_TRAFFICCAR_INFO stTrafficCar;
    /**
     * 公共信息
     */
    public EVENT_COMM_INFO stuCommInfo;
}
package com.ruoyi.device.dhsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.enumeration.EM_CAPTURE_PROCESS_END_TYPE;
import com.ruoyi.device.dhsdk.lib.enumeration.EM_TRIGGER_TYPE;
import static com.ruoyi.device.dhsdk.lib.NetSDKLib.*;
/**
 * 船只的绊线入侵事件信息
 * <p>
 * ERR210428143 水面预警事件 专用结构体
 * <p>
 * 注意: 其他项目不要使用, 通用的绊线入侵事件结构体见:
 * {@link NetSDKLib.DEV_EVENT_CROSSREGION_INFO}
 *
 * @author 47040
 * @since Created in 2021/5/13 17:35
 */
public class DEV_EVENT_CROSSREGION_INFO extends SdkStructure {
    /**
     * 通道号
     */
    public int nChannelID;
    /**
     * 事件名称
     */
    public byte[] szName = new byte[128];
    /**
     * 字节对齐
     */
    public byte[] bReserved1 = new byte[4];
    /**
     * 时间戳(单位是毫秒)
     */
    public double PTS;
    /**
     * 事件发生的时间
     */
    public NET_TIME_EX UTC;
    /**
     * 事件ID
     */
    public int nEventID;
    /**
     * 检测到的物体
     */
    public NET_MSG_OBJECT stuObject;
    /**
     * 事件对应文件信息
     */
    public NET_EVENT_FILE_INFO stuFileInfo;
    /**
     * 规则检测区域
     */
    public NET_POINT[] DetectRegion = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_DETECT_REGION_NUM);
    /**
     * 规则检测区域顶点数
     */
    public int nDetectRegionNum;
    /**
     * 物体运动轨迹
     */
    public NET_POINT[] TrackLine = (NET_POINT[]) new NET_POINT().toArray(NET_MAX_TRACK_LINE_NUM);
    /**
     * 物体运动轨迹顶点数
     */
    public int nTrackLineNum;
    /**
     * 事件动作,0表示脉冲事件,1表示持续性事件开始,2表示持续性事件结束;
     */
    public byte bEventAction;
    /**
     * 表示入侵方向, 0-进入, 1-离开,2-出现,3-消失
     */
    public byte bDirection;
    /**
     * 表示检测动作类型,0-出现 1-消失 2-在区域内 3-穿越区域
     */
    public byte bActionType;
    /**
     * 图片的序号, 同一时间内(精确到秒)可能有多张图片, 从0开始
     */
    public byte byImageIndex;
    /**
     * 抓图标志(按位),具体见NET_RESERVED_COMMON ,
     * 0位:"*",1位:"Timing",2位:"Manual",
     * 3位:"Marked",4位:"Event",5位:"Mosaic",6位:"Cutout"
     */
    public int dwSnapFlagMask;
    /**
     * 事件源设备上的index,-1表示数据无效
     */
    public int nSourceIndex;
    /**
     * 事件源设备唯一标识,字段不存在或者为空表示本地设备
     */
    public byte[] szSourceDevice = new byte[MAX_PATH];
    /**
     * 事件触发累计次数, int 类型
     */
    public int nOccurrenceCount;
    /**
     * 货物通道信息
     */
    public NET_CUSTOM_INFO stuCustom;
    /**
     * 扩展信息
     */
    public NET_EXTENSION_INFO stuExtensionInfo;
    /**
     * 智能事件规则编号,用于标示哪个规则触发的事件
     */
    public int nRuleID;
    /**
     * 热成像横向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoHFOV;
    /**
     * 热成像纵向视场角,单位度,实际角度乘以100 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nThermoVFOV;
    /**
     * 船高 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatHeight;
    /**
     * 船长 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatLength;
    /**
     * 船速 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatSpeed;
    /**
     * 船距 (ERR210428143 专用, 其他项目不要使用)
     */
    public int nBoatDistance;
    /**
     * 保留字节,留待扩展.
     */
    public byte[] bReserved = new byte[300];
    /**
     * 检测到的物体个数
     */
    public int nObjectNum;
    /**
     * 检测到的物体
     */
    public NET_MSG_OBJECT[] stuObjectIDs = (NET_MSG_OBJECT[]) new NET_MSG_OBJECT().toArray(NET_MAX_OBJECT_LIST);
    /**
     * 轨迹数(与检测到的物体个数  nObjectNum 对应)
     */
    public int nTrackNum;
    /**
     * 轨迹信息(与检测到的物体对应)
     */
    public NET_POLY_POINTS[] stuTrackInfo = (NET_POLY_POINTS[]) new NET_POLY_POINTS().toArray(NET_MAX_OBJECT_LIST);
    /**
     * 智能事件公共信息
     */
    public EVENT_INTELLI_COMM_INFO stuIntelliCommInfo;
    /**
     * 全景广角图
     */
    public SCENE_IMAGE_INFO_EX stuSceneImage;
    /**
     * 检测到人的数量
     */
    public int nObjetcHumansNum;
    /**
     * 检测的到人
     */
    public NET_VAOBJECT_NUMMAN[] stuObjetcHumans = (NET_VAOBJECT_NUMMAN[]) new NET_VAOBJECT_NUMMAN().toArray(100);
    /**
     * 车身信息
     */
    public NET_MSG_OBJECT stuVehicle;
    /**
     * 触发类型,参考 {@link EM_TRIGGER_TYPE}
     */
    public int emTriggerType;
    /**
     * 标记抓拍帧
     */
    public int nMark;
    /**
     * 视频分析的数据源地址
     */
    public int nSource;
    /**
     * 视频分析帧序号
     */
    public int nFrameSequence;
    /**
     * 抓拍过程,参考 {@link EM_CAPTURE_PROCESS_END_TYPE}
     */
    public int emCaptureProcess;
    /**
     * 交通车辆信息
     */
    public DEV_EVENT_TRAFFIC_TRAFFICCAR_INFO stTrafficCar;
    /**
     * 公共信息
     */
    public EVENT_COMM_INFO stuCommInfo;
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/EVENT_INTELLI_COMM_INFO.java
@@ -1,34 +1,34 @@
package com.netsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.structure.POSTION;
/**
 * 智能报警事件公共信息
 * <p>
 * ERR210428143 重型云台 水面预警事件 专用结构体
 * <p>
 * 注意: 其他项目不要使用, 通用的停车检测事件结构体见:
 * {@link NetSDKLib.EVENT_INTELLI_COMM_INFO}
 *
 * @author 47040
 * @since Created in 2021/5/13 23:17
 */
public class EVENT_INTELLI_COMM_INFO extends NetSDKLib.SdkStructure {
    /**
     * 智能事件所属大类 取值为 {@link NetSDKLib.EM_CLASS_TYPE } 中的值
     */
    public int emClassType;
    /**
     * 该事件触发的预置点,对应该设置规则的预置点
     */
    public int nPresetID;
    /**
     * 位置信息  (ERR210428143 专用, 其他项目不要使用)
     */
    public POSTION stuPostion;
    /**
     * 保留字节,留待扩展.
     */
    public byte[] bReserved = new byte[112];
}
package com.ruoyi.device.dhsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.structure.POSTION;
/**
 * 智能报警事件公共信息
 * <p>
 * ERR210428143 重型云台 水面预警事件 专用结构体
 * <p>
 * 注意: 其他项目不要使用, 通用的停车检测事件结构体见:
 * {@link NetSDKLib.EVENT_INTELLI_COMM_INFO}
 *
 * @author 47040
 * @since Created in 2021/5/13 23:17
 */
public class EVENT_INTELLI_COMM_INFO extends NetSDKLib.SdkStructure {
    /**
     * 智能事件所属大类 取值为 {@link NetSDKLib.EM_CLASS_TYPE } 中的值
     */
    public int emClassType;
    /**
     * 该事件触发的预置点,对应该设置规则的预置点
     */
    public int nPresetID;
    /**
     * 位置信息  (ERR210428143 专用, 其他项目不要使用)
     */
    public POSTION stuPostion;
    /**
     * 保留字节,留待扩展.
     */
    public byte[] bReserved = new byte[112];
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/lib/structure/customize/MEDIAFILE_FACERECOGNITION_INFO.java
@@ -1,70 +1,70 @@
package com.netsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.Utils;
import com.ruoyi.device.dhsdk.lib.structure.NET_TIME;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author 47081
 * @version 1.0
 * @description ERR210301049主动注册重新定向, 结构体, 日常使用以structure包和NetSDKLib下的同名结构体为主
 * @date 2021/3/17
 */
public class MEDIAFILE_FACERECOGNITION_INFO extends NetSDKLib.SdkStructure {
  /** 结构体大小 */
  public int dwSize;
  /** 报警发生时间 */
  public NET_TIME stTime;
  /** 报警发生地点 */
  public byte[] szAddress = new byte[260];
  /** 通道号 */
  public int nChannelId;
  /** 当前人脸匹配到的候选对象(扩展结构体) 数量 */
  public int nCandidateExNum;
  /** 当前人脸匹配到的候选对象信息, 实际返回个数同nCandidateNum */
 // public CANDIDATE_INFO_CEX[] stuCandidatesEx = (CANDIDATE_INFO_CEX[]) new CANDIDATE_INFO_CEX().toArray(50);
  public CANDIDATE_INFO_CEX[] stuCandidatesEx = new CANDIDATE_INFO_CEX[50];
  public MEDIAFILE_FACERECOGNITION_INFO() {
    for(int i=0;i<stuCandidatesEx.length;i++){
      stuCandidatesEx[i]=new CANDIDATE_INFO_CEX();
    }
    this.dwSize = this.size();
  }
  public void setAddress(String address) {
    byte[] data = address.getBytes(Charset.forName(Utils.getPlatformEncode()));
    System.arraycopy(data, 0, szAddress, 0, data.length);
  }
  public String getAddress() {
    return new String(szAddress, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  public List<CANDIDATE_INFO_CEX> getCandidateInfos() {
    return new ArrayList<>(Arrays.asList(stuCandidatesEx).subList(0, nCandidateExNum));
  }
  @Override
  public String toString() {
    return "MEDIAFILE_FACERECOGNITION_INFO{"
        + "stTime="
        + stTime.toStringTime()
        + ", szAddress="
        + getAddress()
        + ", nChannelId="
        + nChannelId
        + ", nCandidateExNum="
        + nCandidateExNum
        + ", stuCandidatesEx="
        + getCandidateInfos().toString()
        + '}';
  }
}
package com.ruoyi.device.dhsdk.lib.structure.customize;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.Utils;
import com.ruoyi.device.dhsdk.lib.structure.NET_TIME;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author 47081
 * @version 1.0
 * @description ERR210301049主动注册重新定向, 结构体, 日常使用以structure包和NetSDKLib下的同名结构体为主
 * @date 2021/3/17
 */
public class MEDIAFILE_FACERECOGNITION_INFO extends NetSDKLib.SdkStructure {
  /** 结构体大小 */
  public int dwSize;
  /** 报警发生时间 */
  public NET_TIME stTime;
  /** 报警发生地点 */
  public byte[] szAddress = new byte[260];
  /** 通道号 */
  public int nChannelId;
  /** 当前人脸匹配到的候选对象(扩展结构体) 数量 */
  public int nCandidateExNum;
  /** 当前人脸匹配到的候选对象信息, 实际返回个数同nCandidateNum */
 // public CANDIDATE_INFO_CEX[] stuCandidatesEx = (CANDIDATE_INFO_CEX[]) new CANDIDATE_INFO_CEX().toArray(50);
  public CANDIDATE_INFO_CEX[] stuCandidatesEx = new CANDIDATE_INFO_CEX[50];
  public MEDIAFILE_FACERECOGNITION_INFO() {
    for(int i=0;i<stuCandidatesEx.length;i++){
      stuCandidatesEx[i]=new CANDIDATE_INFO_CEX();
    }
    this.dwSize = this.size();
  }
  public void setAddress(String address) {
    byte[] data = address.getBytes(Charset.forName(Utils.getPlatformEncode()));
    System.arraycopy(data, 0, szAddress, 0, data.length);
  }
  public String getAddress() {
    return new String(szAddress, Charset.forName(Utils.getPlatformEncode())).trim();
  }
  public List<CANDIDATE_INFO_CEX> getCandidateInfos() {
    return new ArrayList<>(Arrays.asList(stuCandidatesEx).subList(0, nCandidateExNum));
  }
  @Override
  public String toString() {
    return "MEDIAFILE_FACERECOGNITION_INFO{"
        + "stTime="
        + stTime.toStringTime()
        + ", szAddress="
        + getAddress()
        + ", nChannelId="
        + nChannelId
        + ", nCandidateExNum="
        + nCandidateExNum
        + ", stuCandidatesEx="
        + getCandidateInfos().toString()
        + '}';
  }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/CapturePictureModule.java
@@ -1,106 +1,108 @@
package com.ruoyi.device.dhsdk.module;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.ToolKits;
import com.sun.jna.ptr.IntByReference;
/**
 * \if ENGLISH_LANG
 * Capture Picture Interface
 * contains:local、remote、timer and stop capture picture
 * \else
 * 抓图接口实现
 * 包含: 本地、远程、定时和停止抓图
 * \endif
 */
public class CapturePictureModule {
    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    /**
     * \if ENGLISH_LANG
     * Local Capture Picture
     * \else
     * 本地抓图
     * \endif
     */
    public static boolean localCapturePicture(NetSDKLib.LLong hPlayHandle, String picFileName) {
        if (!netsdk.CLIENT_CapturePictureEx(hPlayHandle, picFileName, NetSDKLib.NET_CAPTURE_FORMATS.NET_CAPTURE_JPEG)) {
            System.err.printf("CLIENT_CapturePicture Failed!" + ToolKits.getErrorCodePrint());
            return false;
        } else {
            System.out.println("CLIENT_CapturePicture success");
        }
        return true;
    }
    /**
     * \if ENGLISH_LANG
     * Remote Capture Picture
     * \else
     * 远程抓图
     * \endif
     */
    public static boolean remoteCapturePicture(NetSDKLib.LLong m_hLoginHandle,int chn) {
        return snapPicture(m_hLoginHandle,chn, 0, 0);
    }
    /**
     * \if ENGLISH_LANG
     * Timer Capture Picture
     * \else
     * 定时抓图
     * \endif
     */
    public static boolean timerCapturePicture(NetSDKLib.LLong m_hLoginHandle,int chn) {
        return snapPicture(m_hLoginHandle,chn, 1, 2);
    }
    /**
     * \if ENGLISH_LANG
     * Stop Timer Capture Picture
     * \else
     * 停止定时抓图
     * \endif
     */
    public static boolean stopCapturePicture(NetSDKLib.LLong m_hLoginHandle,int chn) {
        return snapPicture(m_hLoginHandle,chn, -1, 0);
    }
    /**
     * \if ENGLISH_LANG
     * Capture Picture (except local capture picture, others all call this interface)
     * \else
     * 抓图 (除本地抓图外, 其他全部调用此接口)
     * \endif
     */
    private static boolean snapPicture(NetSDKLib.LLong m_hLoginHandle,int chn, int mode, int interval) {
        // send caputre picture command to device
        NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS();
        stuSnapParams.Channel = chn;              // channel
        stuSnapParams.mode = mode;                // capture picture mode
        stuSnapParams.Quality = 3;                // picture quality
        stuSnapParams.InterSnap = interval;     // timer capture picture time interval
        stuSnapParams.CmdSerial = 0;              // request serial
        IntByReference reserved = new IntByReference(0);
        if (!LoginModule.netsdk.CLIENT_SnapPictureEx(m_hLoginHandle, stuSnapParams, reserved)) {
            System.err.printf("CLIENT_SnapPictureEx Failed!" + ToolKits.getErrorCodePrint());
            return false;
        } else {
            System.out.println("CLIENT_SnapPictureEx success");
        }
        return true;
    }
    /**
     * \if ENGLISH_LANG
     * Set Capture Picture Callback
     * \else
     * 设置抓图回调函数
     * \endif
     */
    public static void setSnapRevCallBack(NetSDKLib.fSnapRev cbSnapReceive){
        LoginModule.netsdk.CLIENT_SetSnapRevCallBack(cbSnapReceive, null);
    }
}
package com.ruoyi.device.dhsdk.module;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.ToolKits;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
/**
 * \if ENGLISH_LANG
 * Capture Picture Interface
 * contains:local、remote、timer and stop capture picture
 * \else
 * 抓图接口实现
 * 包含: 本地、远程、定时和停止抓图
 * \endif
 */
@Slf4j(topic = "dhSdk")
public class CapturePictureModule {
    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    /**
     * \if ENGLISH_LANG
     * Local Capture Picture
     * \else
     * 本地抓图
     * \endif
     */
    public static boolean localCapturePicture(NetSDKLib.LLong hPlayHandle, String picFileName) {
        if (!netsdk.CLIENT_CapturePictureEx(hPlayHandle, picFileName, NetSDKLib.NET_CAPTURE_FORMATS.NET_CAPTURE_JPEG)) {
            log.error("CLIENT_CapturePicture Failed!" + ToolKits.getErrorCodePrint());
            return false;
        } else {
            log.debug("CLIENT_CapturePicture success");
        }
        return true;
    }
    /**
     * \if ENGLISH_LANG
     * Remote Capture Picture
     * \else
     * 远程抓图
     * \endif
     */
    public static boolean remoteCapturePicture(NetSDKLib.LLong m_hLoginHandle,int chn) {
        return snapPicture(m_hLoginHandle,chn, 0, 0);
    }
    /**
     * \if ENGLISH_LANG
     * Timer Capture Picture
     * \else
     * 定时抓图
     * \endif
     */
    public static boolean timerCapturePicture(NetSDKLib.LLong m_hLoginHandle,int chn) {
        return snapPicture(m_hLoginHandle,chn, 1, 2);
    }
    /**
     * \if ENGLISH_LANG
     * Stop Timer Capture Picture
     * \else
     * 停止定时抓图
     * \endif
     */
    public static boolean stopCapturePicture(NetSDKLib.LLong m_hLoginHandle,int chn) {
        return snapPicture(m_hLoginHandle,chn, -1, 0);
    }
    /**
     * \if ENGLISH_LANG
     * Capture Picture (except local capture picture, others all call this interface)
     * \else
     * 抓图 (除本地抓图外, 其他全部调用此接口)
     * \endif
     */
    private static boolean snapPicture(NetSDKLib.LLong m_hLoginHandle,int chn, int mode, int interval) {
        // send caputre picture command to device
        NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS();
        stuSnapParams.Channel = chn;              // channel
        stuSnapParams.mode = mode;                // capture picture mode
        stuSnapParams.Quality = 3;                // picture quality
        stuSnapParams.InterSnap = interval;     // timer capture picture time interval
        stuSnapParams.CmdSerial = 0;              // request serial
        IntByReference reserved = new IntByReference(0);
        if (!LoginModule.netsdk.CLIENT_SnapPictureEx(m_hLoginHandle, stuSnapParams, reserved)) {
            log.error("CLIENT_SnapPictureEx Failed!" + ToolKits.getErrorCodePrint());
            return false;
        } else {
            log.debug("CLIENT_SnapPictureEx success");
        }
        return true;
    }
    /**
     * \if ENGLISH_LANG
     * Set Capture Picture Callback
     * \else
     * 设置抓图回调函数
     * \endif
     */
    public static void setSnapRevCallBack(NetSDKLib.fSnapRev cbSnapReceive){
        LoginModule.netsdk.CLIENT_SetSnapRevCallBack(cbSnapReceive, null);
    }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/ConfigModule.java
@@ -4,6 +4,7 @@
import com.ruoyi.device.dhsdk.lib.ToolKits;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import static com.ruoyi.device.dhsdk.lib.ToolKits.getErrorCodePrint;
@@ -13,6 +14,7 @@
 * @Author: 刘苏义
 * @Date: 2023年10月14日14:57:01
 **/
@Slf4j(topic = "dhSdk")
public class ConfigModule {
    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    public static NetSDKLib configsdk = NetSDKLib.CONFIG_INSTANCE;
@@ -39,7 +41,7 @@
        IntByReference intRetLen = new IntByReference();
        stuInfo.write();
        if (!netsdk.CLIENT_QueryRemotDevState(hLoginHandle, nType, nChn, stuInfo.getPointer(), stuInfo.size(), intRetLen, 3000)) {
            System.err.println("Config Failed!" + ToolKits.getErrorCodePrint());
            log.error("Config Failed!" + ToolKits.getErrorCodePrint());
            return false;
        }
        stuInfo.read();
@@ -67,11 +69,11 @@
                cmdObject.read();
                result = true;
            } else {
                System.err.println("Parse " + strCmd + " Config Failed!" + ToolKits.getErrorCodePrint());
                log.error("Parse " + strCmd + " Config Failed!" + ToolKits.getErrorCodePrint());
                result = false;
            }
        } else {
            System.err.printf("Get %s Config Failed!Last Error = %s\n", strCmd, getErrorCodePrint());
            log.error("Get %s Config Failed!Last Error = %s\n", strCmd, getErrorCodePrint());
            result = false;
        }
@@ -88,7 +90,7 @@
        if (bRet) {
            cmdObject.read();
        } else {
            System.err.printf("Get %s Config Failed!Last Error = %s\n", strCmd, getErrorCodePrint());
            log.error("Get %s Config Failed!Last Error = %s\n", strCmd, getErrorCodePrint());
            result = false;
        }
        return result;
@@ -102,7 +104,7 @@
            cmdObject.read();
            result=true;
        } else {
            System.err.println("GetConfig Failed!" + getErrorCodePrint());
            log.error("GetConfig Failed!" + getErrorCodePrint());
            result=false;
        }
        return result;
@@ -129,11 +131,11 @@
            if (netsdk.CLIENT_SetNewDevConfig(hLoginHandle, strCmd, nChn, szBuffer, nBufferLen, error, restart, 3000)) {
                result = true;
            } else {
                System.err.printf("Set %s Config Failed! Last Error = %s\n", strCmd, getErrorCodePrint());
                log.error("Set %s Config Failed! Last Error = %s\n", strCmd, getErrorCodePrint());
                result = false;
            }
        } else {
            System.err.println("Packet " + strCmd + " Config Failed!" + getErrorCodePrint());
            log.error("Packet " + strCmd + " Config Failed!" + getErrorCodePrint());
            result = false;
        }
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/LoginModule.java
@@ -1,146 +1,145 @@
package com.ruoyi.device.dhsdk.module;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.NetSDKLib.LLong;
import com.ruoyi.device.dhsdk.lib.NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.ruoyi.device.dhsdk.lib.NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import static com.ruoyi.device.dhsdk.lib.ToolKits.getErrorCodePrint;
/**
 * 登陆接口实现
 * 主要有 :初始化、登陆、登出功能
 */
@Slf4j(topic = "dhSdk")
public class LoginModule {
    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    // 设备信息
    public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
    // 登陆句柄
    public static LLong m_hLoginHandle = new LLong(0);//
    private static boolean bInit = false;
    private static boolean bLogopen = false;
    /**
     * \if ENGLISH_LANG
     * Init
     * \else
     * 初始化
     * \endif
     */
    public static boolean init(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {
        bInit = netsdk.CLIENT_Init(disConnect, null);
        if (!bInit) {
            log.debug("Initialize SDK failed");
            return false;
        }
        //打开日志,可选
        //NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        //File path = new File("./sdklog/");
        //if (!path.exists()) {
        //    path.mkdir();
        //}
        //String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + ToolKits.getDate() + ".log";
        //setLog.nPrintStrategy = 0;
        //setLog.bSetFilePath = 1;
        //System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        //System.out.println(logPath);
        //setLog.bSetPrintStrategy = 1;
        //bLogopen = netsdk.CLIENT_LogOpen(setLog);
      //  if (!bLogopen) {
           // System.err.println("Failed to open NetSDK log");
       // }
        // 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作
        // 此操作为可选操作,但建议用户进行设置
        netsdk.CLIENT_SetAutoReconnect(haveReConnect, null);
        //设置登录超时时间和尝试次数,可选
        int waitTime = 5000; //登录请求响应超时时间设置为5S
        int tryTimes = 1;    //登录时尝试建立链接1次
        netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);
        // 设置更多网络参数,NET_PARAM的nWaittime,nConnectTryNum成员与CLIENT_SetConnectTime
        // 接口设置的登录设备超时时间和尝试次数意义相同,可选
        NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
        netParam.nConnectTime = 10000;      // 登录时尝试建立链接的超时时间
        netParam.nGetConnInfoTime = 3000;   // 设置子连接的超时时间
        netParam.nGetDevInfoTime = 3000;//获取设备信息超时时间,为0默认1000ms
        netsdk.CLIENT_SetNetworkParam(netParam);
        return true;
    }
    /**
     * \if ENGLISH_LANG
     * CleanUp
     * \else
     * 清除环境
     * \endif
     */
    public static void cleanup() {
        if (bLogopen) {
            netsdk.CLIENT_LogClose();
        }
        if (bInit) {
            netsdk.CLIENT_Cleanup();
        }
    }
    /**
     * \if ENGLISH_LANG
     * Login Device
     * \else
     * 登录设备
     * \endif
     */
    public static LLong login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
        IntByReference nError = new IntByReference(0);
        //入参
        NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstInParam.nPort = m_nPort;
        pstInParam.szIP = m_strIp.getBytes();
        pstInParam.szPassword = m_strPassword.getBytes();
        pstInParam.szUserName = m_strUser.getBytes();
        //出参
        NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstOutParam.stuDeviceInfo = m_stDeviceInfo;
        LLong m_hLoginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, 0, null, m_stDeviceInfo, nError);
        //m_hLoginHandle=netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
        if (m_hLoginHandle.longValue() == 0) {
            log.debug("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort, getErrorCodePrint());
        } else {
            log.debug("Login Success [ " + m_strIp + " ]");
        }
        return m_hLoginHandle;
        //return m_hLoginHandle.longValue() == 0? false:true;
    }
    /**
     * \if ENGLISH_LANG
     * Logout Device
     * \else
     * 登出设备
     * \endif
     */
    public static boolean logout(LLong loginId) {
        if (loginId.longValue() == 0) {
            return false;
        }
        boolean bRet = netsdk.CLIENT_Logout(loginId);
        if (bRet) {
            loginId.setValue(0);
        }
        return bRet;
    }
package com.ruoyi.device.dhsdk.module;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.NetSDKLib.LLong;
import com.ruoyi.device.dhsdk.lib.NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.ruoyi.device.dhsdk.lib.NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import static com.ruoyi.device.dhsdk.lib.ToolKits.getErrorCodePrint;
/**
 * 登陆接口实现
 * 主要有 :初始化、登陆、登出功能
 */
@Slf4j(topic = "dhSdk")
public class LoginModule {
    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    // 设备信息
    public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
    // 登陆句柄
    public static LLong m_hLoginHandle = new LLong(0);//
    private static boolean bInit = false;
    private static boolean bLogopen = false;
    /**
     * \if ENGLISH_LANG
     * Init
     * \else
     * 初始化
     * \endif
     */
    public static boolean init(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {
        bInit = netsdk.CLIENT_Init(disConnect, null);
        if (!bInit) {
            log.debug("Initialize SDK failed");
            return false;
        }
        //打开日志,可选
        //NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        //File path = new File("./sdklog/");
        //if (!path.exists()) {
        //    path.mkdir();
        //}
        //String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + ToolKits.getDate() + ".log";
        //setLog.nPrintStrategy = 0;
        //setLog.bSetFilePath = 1;
        //System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        //System.out.println(logPath);
        //setLog.bSetPrintStrategy = 1;
        //bLogopen = netsdk.CLIENT_LogOpen(setLog);
      //  if (!bLogopen) {
           // System.err.println("Failed to open NetSDK log");
       // }
        // 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作
        // 此操作为可选操作,但建议用户进行设置
        netsdk.CLIENT_SetAutoReconnect(haveReConnect, null);
        //设置登录超时时间和尝试次数,可选
        int waitTime = 5000; //登录请求响应超时时间设置为5S
        int tryTimes = 1;    //登录时尝试建立链接1次
        netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);
        // 设置更多网络参数,NET_PARAM的nWaittime,nConnectTryNum成员与CLIENT_SetConnectTime
        // 接口设置的登录设备超时时间和尝试次数意义相同,可选
        NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
        netParam.nConnectTime = 10000;      // 登录时尝试建立链接的超时时间
        netParam.nGetConnInfoTime = 3000;   // 设置子连接的超时时间
        netParam.nGetDevInfoTime = 3000;//获取设备信息超时时间,为0默认1000ms
        netsdk.CLIENT_SetNetworkParam(netParam);
        return true;
    }
    /**
     * \if ENGLISH_LANG
     * CleanUp
     * \else
     * 清除环境
     * \endif
     */
    public static void cleanup() {
        if (bLogopen) {
            netsdk.CLIENT_LogClose();
        }
        if (bInit) {
            netsdk.CLIENT_Cleanup();
        }
    }
    /**
     * \if ENGLISH_LANG
     * Login Device
     * \else
     * 登录设备
     * \endif
     */
    public static LLong login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
        IntByReference nError = new IntByReference(0);
        //入参
        NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstInParam.nPort = m_nPort;
        pstInParam.szIP = m_strIp.getBytes();
        pstInParam.szPassword = m_strPassword.getBytes();
        pstInParam.szUserName = m_strUser.getBytes();
        //出参
        NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstOutParam.stuDeviceInfo = m_stDeviceInfo;
        LLong m_hLoginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, 0, null, m_stDeviceInfo, nError);
        //m_hLoginHandle=netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
        if (m_hLoginHandle.longValue() == 0) {
            log.debug("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort, getErrorCodePrint());
        } else {
            log.debug("Login Success [ " + m_strIp + ":" + m_nPort + " ]");
        }
        return m_hLoginHandle;
    }
    /**
     * \if ENGLISH_LANG
     * Logout Device
     * \else
     * 登出设备
     * \endif
     */
    public static boolean logout(LLong loginId) {
        if (loginId.longValue() == 0) {
            return false;
        }
        boolean bRet = netsdk.CLIENT_Logout(loginId);
        if (bRet) {
            loginId.setValue(0);
        }
        return bRet;
    }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/module/RealPlayModule.java
@@ -1,102 +1,104 @@
package com.ruoyi.device.dhsdk.module;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import static com.ruoyi.device.dhsdk.module.LoginModule.netsdk;
/**
 * 实时预览接口实现
 * 主要有 :开始拉流、停止拉流功能
 */
public class RealPlayModule {
    /**
     * \if ENGLISH_LANG
     * Start RealPlay
     * \else
     * 开始预览
     * \endif
     */
    public static NetSDKLib.LLong startRealPlay(NetSDKLib.LLong m_hLoginHandle, int channel, String path) {
        NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE net_in_realplay_by_data_type = new NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE();
        net_in_realplay_by_data_type.nChannelID = channel;
        net_in_realplay_by_data_type.hWnd = null;
        net_in_realplay_by_data_type.rType = 0;
        net_in_realplay_by_data_type.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_MP4;
        net_in_realplay_by_data_type.szSaveFileName = path;
        NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE net_out_realplay_by_data_type = new NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE();
        NetSDKLib.LLong m_hPlayHandle = netsdk.CLIENT_RealPlayByDataType(m_hLoginHandle, net_in_realplay_by_data_type, net_out_realplay_by_data_type, 5000);
        if (m_hPlayHandle.longValue() == 0) {
            System.err.println("开始实时预览失败,错误码" + ToolKits.getErrorCodePrint());
        } else {
            System.out.println("Success to start realplay");
        }
        return m_hPlayHandle;
    }
    /**
     * \if ENGLISH_LANG
     * Stop RealPlay
     * \else
     * 停止预览
     * \endif
     */
    public static void stopRealPlay(NetSDKLib.LLong m_hPlayHandle) {
        if (m_hPlayHandle.longValue() == 0) {
            return;
        }
        boolean bRet = netsdk.CLIENT_StopRealPlayEx(m_hPlayHandle);
        if (bRet) {
            m_hPlayHandle.setValue(0);
        }
    }
    /**
     * 实时预览数据回调函数--扩展(pBuffer内存由SDK内部申请释放)
     */
    private static class CbfRealDataCallBackEx implements NetSDKLib.fRealDataCallBackEx {
        private CbfRealDataCallBackEx() {
        }
        private static class CallBackHolder {
            private static CbfRealDataCallBackEx instance = new CbfRealDataCallBackEx();
        }
        public static CbfRealDataCallBackEx getInstance() {
            return CallBackHolder.instance;
        }
        @Override
        public void invoke(NetSDKLib.LLong lRealHandle, int dwDataType, Pointer pBuffer,
                           int dwBufSize, int param, Pointer dwUser) {
            int bInput = 0;
            if (0 != lRealHandle.longValue()) {
                switch (dwDataType) {
                    case 0:
                        System.out.println("码流大小为" + dwBufSize + "\n" + "码流类型为原始音视频混合数据");
                        break;
                    case 1:
                        //标准视频数据
                        System.out.println("码流大小为" + dwBufSize + "\n" + "码流类型为标准视频数据");
                        break;
                    case 2:
                        //yuv 数据
                        System.out.println("码流大小为" + dwBufSize + "\n" + "码流类型为yuv数据");
                        break;
                    case 3:
                        //pcm 音频数据
                        System.out.println("码流大小为" + dwBufSize + "\n" + "码流类型为音频数据");
                        break;
                    case 4:
                        //原始音频数据
                        System.out.println("码流大小为" + dwBufSize + "\n" + "码流类型为原始音频数据");
                        break;
                    default:
                        break;
                }
            }
        }
    }
package com.ruoyi.device.dhsdk.module;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.dhsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import static com.ruoyi.device.dhsdk.module.LoginModule.netsdk;
/**
 * 实时预览接口实现
 * 主要有 :开始拉流、停止拉流功能
 */
@Slf4j(topic = "dhSdk")
public class RealPlayModule {
    /**
     * \if ENGLISH_LANG
     * Start RealPlay
     * \else
     * 开始预览
     * \endif
     */
    public static NetSDKLib.LLong startRealPlay(NetSDKLib.LLong m_hLoginHandle, int channel, String path) {
        NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE net_in_realplay_by_data_type = new NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE();
        net_in_realplay_by_data_type.nChannelID = channel;
        net_in_realplay_by_data_type.hWnd = null;
        net_in_realplay_by_data_type.rType = 0;
        net_in_realplay_by_data_type.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_MP4;
        net_in_realplay_by_data_type.szSaveFileName = path;
        NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE net_out_realplay_by_data_type = new NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE();
        NetSDKLib.LLong m_hPlayHandle = netsdk.CLIENT_RealPlayByDataType(m_hLoginHandle, net_in_realplay_by_data_type, net_out_realplay_by_data_type, 5000);
        if (m_hPlayHandle.longValue() == 0) {
            log.error("开始实时预览失败,错误码" + ToolKits.getErrorCodePrint());
        } else {
            log.debug("Success to start realplay");
        }
        return m_hPlayHandle;
    }
    /**
     * \if ENGLISH_LANG
     * Stop RealPlay
     * \else
     * 停止预览
     * \endif
     */
    public static void stopRealPlay(NetSDKLib.LLong m_hPlayHandle) {
        if (m_hPlayHandle.longValue() == 0) {
            return;
        }
        boolean bRet = netsdk.CLIENT_StopRealPlayEx(m_hPlayHandle);
        if (bRet) {
            m_hPlayHandle.setValue(0);
        }
    }
    /**
     * 实时预览数据回调函数--扩展(pBuffer内存由SDK内部申请释放)
     */
    private static class CbfRealDataCallBackEx implements NetSDKLib.fRealDataCallBackEx {
        private CbfRealDataCallBackEx() {
        }
        private static class CallBackHolder {
            private static CbfRealDataCallBackEx instance = new CbfRealDataCallBackEx();
        }
        public static CbfRealDataCallBackEx getInstance() {
            return CallBackHolder.instance;
        }
        @Override
        public void invoke(NetSDKLib.LLong lRealHandle, int dwDataType, Pointer pBuffer,
                           int dwBufSize, int param, Pointer dwUser) {
            int bInput = 0;
            if (0 != lRealHandle.longValue()) {
                switch (dwDataType) {
                    case 0:
                        log.debug("码流大小为" + dwBufSize + "\n" + "码流类型为原始音视频混合数据");
                        break;
                    case 1:
                        //标准视频数据
                        log.debug("码流大小为" + dwBufSize + "\n" + "码流类型为标准视频数据");
                        break;
                    case 2:
                        //yuv 数据
                        log.debug("码流大小为" + dwBufSize + "\n" + "码流类型为yuv数据");
                        break;
                    case 3:
                        //pcm 音频数据
                        log.debug("码流大小为" + dwBufSize + "\n" + "码流类型为音频数据");
                        break;
                    case 4:
                        //原始音频数据
                        log.debug("码流大小为" + dwBufSize + "\n" + "码流类型为原始音频数据");
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
ard-work/src/main/java/com/ruoyi/device/dhsdk/service/IDhClientService.java
@@ -13,8 +13,6 @@
 */
public interface IDhClientService {
    //sdk初始化
    Boolean init();
    //登录
    Boolean login(ArdCameras ardCamera);
ard-work/src/main/java/com/ruoyi/device/dhsdk/service/impl/DhClientServiceImpl.java
@@ -77,7 +77,7 @@
            List<ArdCameras> ardCameras = ardCamerasService.selectArdCamerasListNoDataScope(ardCamera);
            for (ArdCameras camera : ardCameras) {
                Thread.sleep(500);
                //异步登录
                //登录
                login(camera);
            }
        } catch (Exception ex) {
@@ -85,15 +85,6 @@
        }
    }
    /**
     * sdk初始化
     * 刘苏义
     * 2023/10/17 8:28:13
     */
    @Override
    public Boolean init() {
        return LoginModule.init(disConnect, haveReConnect);   // 打开工程,初始化
    }
    /**
     * 登录
@@ -101,8 +92,8 @@
     * 2023/10/17 8:28:13
     */
    @Override
    @Async
    public Boolean login(ArdCameras camera) {
        LoginModule.init(disConnect, haveReConnect);
        LLong loginId = LoginModule.login(camera.getIp(), camera.getPort(), camera.getUsername(), camera.getPassword());
        if (loginId.longValue() > 0) {
            //log.debug(camera.getIp() + ":" + camera.getPort() + "登录成功");
@@ -168,7 +159,6 @@
            ardCamerasService.updateArdCameras(camera);
            return false;
        }
        return true;
    }
@@ -912,7 +902,7 @@
    // 设备断线回调: 当设备出现断线时,SDK会调用该函数
    private static class DisConnect implements NetSDKLib.fDisConnect {
        public void invoke(LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
            log.warn("Device["+pchDVRIP+"] Port["+nDVRPort+"] DisConnect!");
        }
    }
@@ -920,7 +910,7 @@
    private static class HaveReConnect implements NetSDKLib.fHaveReConnect {
        @Override
        public void invoke(LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);
            log.warn("ReConnect Device["+pchDVRIP+"] Port["+nDVRPort+"]");
        }
    }
ard-work/src/main/java/com/ruoyi/device/hiksdk/common/GlobalVariable.java
@@ -1,22 +1,25 @@
package com.ruoyi.device.hiksdk.common;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
 * @ClassName: globalVariable
 * @Description: 全局变量
 * @Author: Administrator
 * @Date: 2023年01月31日 17:05
 * @Version: 1.0
 **/
@Data
public class GlobalVariable {
    //保存相机登录信息
    public static Map<String, Object> loginMap = new HashMap<>();
    //相机预览字典
    public static Map<String, Integer> previewMap = new HashMap<>();
    //线程字典
    public static Map<String,String>threadMap=new HashMap<>();
}
package com.ruoyi.device.hiksdk.common;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
 * @ClassName: globalVariable
 * @Description: 全局变量
 * @Author: Administrator
 * @Date: 2023年01月31日 17:05
 * @Version: 1.0
 **/
@Data
public class GlobalVariable {
    //保存相机登录信息
    public static Map<String, Object> loginMap = new HashMap<>();
    //相机预览字典
    public static Map<String, Integer> previewMap = new HashMap<>();
    //线程字典
    public static Map<String,String>threadMap=new HashMap<>();
    //保存相机登录信息(loginId:Camera)
    public static Map<Integer, Object> loginCameraMap = new HashMap<>();
}
ard-work/src/main/java/com/ruoyi/device/hiksdk/sdk/ExceptionCallBack.java
对比新文件
@@ -0,0 +1,44 @@
package com.ruoyi.device.hiksdk.sdk;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.hiksdk.common.GlobalVariable;
import com.sun.jna.Pointer;
import javafx.scene.Camera;
import lombok.extern.slf4j.Slf4j;
import static com.ruoyi.device.hiksdk.sdk.HCNetSDK.*;
/**
 * @Description: 注册接收异常、重连等消息的窗口句柄或回调函数
 * @ClassName: ExceptionCallBack
 * @Author: 刘苏义
 * @Date: 2023年10月23日15:37:40
 **/
@Slf4j(topic = "hikSdk")
public class ExceptionCallBack implements HCNetSDK.FExceptionCallBack {
    @Override
    public void invoke(int dwType, int lUserID, int lHandle, Pointer pUser) {
        ArdCameras camera = (ArdCameras) GlobalVariable.loginCameraMap.get(lUserID);
        if(camera!=null) {
            String ip = camera.getIp();
            Integer port = camera.getPort();
            switch (dwType) {
                case EXCEPTION_EXCHANGE:
                    log.warn("Device[" + ip + "] Port[" + port + "]用户交互时异常");
                    break;
                case EXCEPTION_PREVIEW:
                    log.warn("Device[" + ip + "] Port[" + port + "]网络预览异常");
                    break;
                case EXCEPTION_RECONNECT:
                    log.warn("Device[" + ip + "] Port[" + port + "]预览时重连");
                    break;
                case RELOGIN_SUCCESS:
                    log.warn("Device[" + ip + "] Port[" + port + "]用户重登陆成功");
                    break;
                case EXCEPTION_RELOGIN:
                    log.warn("Device[" + ip + "] Port[" + port + "]用户重登陆");
                    break;
            }
        }
    }
}
ard-work/src/main/java/com/ruoyi/device/hiksdk/sdk/HCNetSDK.java
文件太大
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/IHikClientService.java
@@ -1,114 +1,112 @@
package com.ruoyi.device.hiksdk.service;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.channel.domain.ArdChannel;
import java.util.List;
import java.util.Map;
/**
 * @ClassName: IHikClientService
 * @Description: 海康操作客户端接口类
 * @Author: Administrator
 * @Date: 2023年01月17日 15:59
 * @Version: 1.0
 **/
public interface IHikClientService {
    //sdk初始化
    boolean init();
    //同步登录
    void syncLogin(ArdCameras cameras);
    //异步登录
    void asyncLogin(ArdCameras cameras);
    //登录所有相机
    void loginAll();
    //注销
    boolean logout(String cameraId);
    //在线状态
    boolean isOnLine(CameraCmd cmd);
    //云台控制
    boolean pTZControlWithSpeed(CameraCmd cmd);
    //设置聚焦值
    boolean setFocusPos(CameraCmd cmd);
    //获取聚焦值
    int getFocusPos(CameraCmd cmd);
    //设置预置位
    boolean setPreset(CameraCmd cmd);
    //调用预置位
    boolean gotoPreset(CameraCmd cmd);
    //获取码流压缩参数
    Map<String, Object> getVideoCompressionCfg(CameraCmd cmd);
    //透雾
    boolean controlDefogcfg(CameraCmd cmd);
    //红外
    boolean controlInfrarecfg(CameraCmd cmd);
    //聚焦模式
    boolean controlFocusMode(CameraCmd cmd);
    //获取聚焦模式
    String getFocusMode(CameraCmd cmd);
    //云台加热
    boolean controlPTHeateRpwron(CameraCmd cmd);
    //镜头除冰
    boolean controlCameraDeicing(CameraCmd cmd);
    //获取云台锁定信息
    int getPTZLockInfo(CameraCmd cmd);
    //抓图-返给前端二进制流
    String captureJPEGPicture(CameraCmd cmd);
    //抓图
    String picCutCate(CameraCmd cmd);
    //ptz 三坐标
    Map<String, Object> getPtz(CameraCmd cmd);
    //获取ptz范围
    Map<String, Object> getPtzScope(CameraCmd cmd);
    //设置ptz
    boolean setPtz(CameraCmd cmd);
    //设置零方位角
    boolean setZeroPtz(CameraCmd cmd);
    //手动录像
    String record(CameraCmd cmd);
    //引导目标位置
    boolean guideTargetPosition(CameraCmd cmd);
    //开始录像
    boolean recordStart(CameraCmd cmd);
    //停止录像-上传minio-返回录像url
    String recordStopToMinio(CameraCmd cmd);
    //停止录像-不上传minio
    boolean recordStopNotToMinio(CameraCmd cmd);
    //获取相机通道信息
    public List<ArdChannel> getCameraChannelList(ArdCameras camera);
    //获取GIS信息数据
    public Map<String, Object> getGisInfo(CameraCmd cmd);
}
package com.ruoyi.device.hiksdk.service;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.channel.domain.ArdChannel;
import java.util.List;
import java.util.Map;
/**
 * @ClassName: IHikClientService
 * @Description: 海康操作客户端接口类
 * @Author: Administrator
 * @Date: 2023年01月17日 15:59
 * @Version: 1.0
 **/
public interface IHikClientService {
    //同步登录
    void login(ArdCameras cameras);
    //异步登录
    void asyncLogin(ArdCameras cameras);
    //登录所有相机
    void loginAll();
    //注销
    boolean logout(String cameraId);
    //在线状态
    boolean isOnLine(CameraCmd cmd);
    //云台控制
    boolean pTZControlWithSpeed(CameraCmd cmd);
    //设置聚焦值
    boolean setFocusPos(CameraCmd cmd);
    //获取聚焦值
    int getFocusPos(CameraCmd cmd);
    //设置预置位
    boolean setPreset(CameraCmd cmd);
    //调用预置位
    boolean gotoPreset(CameraCmd cmd);
    //获取码流压缩参数
    Map<String, Object> getVideoCompressionCfg(CameraCmd cmd);
    //透雾
    boolean controlDefogcfg(CameraCmd cmd);
    //红外
    boolean controlInfrarecfg(CameraCmd cmd);
    //聚焦模式
    boolean controlFocusMode(CameraCmd cmd);
    //获取聚焦模式
    String getFocusMode(CameraCmd cmd);
    //云台加热
    boolean controlPTHeateRpwron(CameraCmd cmd);
    //镜头除冰
    boolean controlCameraDeicing(CameraCmd cmd);
    //获取云台锁定信息
    int getPTZLockInfo(CameraCmd cmd);
    //抓图-返给前端二进制流
    String captureJPEGPicture(CameraCmd cmd);
    //抓图
    String picCutCate(CameraCmd cmd);
    //ptz 三坐标
    Map<String, Object> getPtz(CameraCmd cmd);
    //获取ptz范围
    Map<String, Object> getPtzScope(CameraCmd cmd);
    //设置ptz
    boolean setPtz(CameraCmd cmd);
    //设置零方位角
    boolean setZeroPtz(CameraCmd cmd);
    //手动录像
    String record(CameraCmd cmd);
    //引导目标位置
    boolean guideTargetPosition(CameraCmd cmd);
    //开始录像
    boolean recordStart(CameraCmd cmd);
    //停止录像-上传minio-返回录像url
    String recordStopToMinio(CameraCmd cmd);
    //停止录像-不上传minio
    boolean recordStopNotToMinio(CameraCmd cmd);
    //获取相机通道信息
    public List<ArdChannel> getCameraChannelList(ArdCameras camera);
    //获取GIS信息数据
    public Map<String, Object> getGisInfo(CameraCmd cmd);
}
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java
@@ -10,8 +10,11 @@
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.channel.domain.ArdChannel;
import com.ruoyi.device.channel.service.IArdChannelService;
import com.ruoyi.device.dhsdk.lib.LibraryLoad;
import com.ruoyi.device.dhsdk.lib.NetSDKLib;
import com.ruoyi.device.hiksdk.common.GlobalVariable;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.hiksdk.sdk.ExceptionCallBack;
import com.ruoyi.media.domain.Vtdu;
import com.ruoyi.media.service.IVtduService;
import com.ruoyi.utils.gis.GisUtil;
@@ -37,6 +40,7 @@
import java.util.*;
import java.util.concurrent.PriorityBlockingQueue;
import static com.ruoyi.device.hiksdk.common.GlobalVariable.loginCameraMap;
import static com.ruoyi.device.hiksdk.sdk.HCNetSDK.*;
/**
@@ -57,52 +61,10 @@
    @Resource
    private IVtduService vtduService;
    private static HCNetSDK hCNetSDK;
    public static HCNetSDK hCNetSDK = HCNetSDK.hCNetSDK;
    private static FExceptionCallBack fExceptionCallBack;//异常回调
    @Override
    public boolean init() {
        try {
            log.debug("开始加载sdk库文件路径");
            if (Platform.isWindows()) {
                String WIN_PATH = System.getProperty("user.dir") + File.separator + "lib\\hikDll\\HCNetSDK.dll";
                log.debug("当前Windows平台的sdk库路径:" + WIN_PATH);
                hCNetSDK = (HCNetSDK) Native.loadLibrary(WIN_PATH, HCNetSDK.class);
            } else {
                log.debug("Linux平台");
                String LINUX_PATH = System.getProperty("user.dir") + File.separator + "hiklib" + File.separator + "libhcnetsdk.so";
                log.debug("当前Linux平台的sdk库路径:" + LINUX_PATH);
                hCNetSDK = (HCNetSDK) Native.loadLibrary(LINUX_PATH, HCNetSDK.class);
                //设置HCNetSDKCom组件库所在路径
                //libhcnetsdk.so
                String strPathCom = "/home/hiklib";
                NET_DVR_LOCAL_SDK_PATH struComPath = new NET_DVR_LOCAL_SDK_PATH();
                System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
                struComPath.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
                //设置libcrypto.so所在路径
                BYTE_ARRAY ptrByteArrayCrypto = new BYTE_ARRAY(256);
                String strPathCrypto = "/home/hiklib/libcrypto.so.1.1";
                System.arraycopy(strPathCrypto.getBytes(), 0, ptrByteArrayCrypto.byValue, 0, strPathCrypto.length());
                ptrByteArrayCrypto.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArrayCrypto.getPointer());
                //设置libssl.so所在路径
                BYTE_ARRAY ptrByteArraySsl = new BYTE_ARRAY(256);
                String strPathSsl = "/home/hiklib/libssl.so.1.1";
                System.arraycopy(strPathSsl.getBytes(), 0, ptrByteArraySsl.byValue, 0, strPathSsl.length());
                ptrByteArraySsl.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArraySsl.getPointer());
            }
            return true;
        } catch (Exception ex) {
            log.error("加载库文件异常:" + ex.getMessage());
            return false;
        }
    }
    @Override
    /**
     * @描述 注册登录 只支持同步登陆,且官方不建议直接在此接口下写耗时操作
     * @参数 [dvrLogin]
@@ -111,8 +73,8 @@
     * @创建时间 2023/1/17 16:12
     * @修改人和其它信息
     */
    @Async
    public void syncLogin(ArdCameras camera) {
    @Override
    public void login(ArdCameras camera) {
        // 初始化
        if (!hCNetSDK.NET_DVR_Init()) {
            log.error("SDK初始化失败");
@@ -130,7 +92,7 @@
        short m_sPort = camera.getPort().shortValue();
        //设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(100000, true);
        hCNetSDK.NET_DVR_SetReconnect(5000, true);
        //设备信息, 输出参数
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
@@ -152,13 +114,21 @@
        int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (lUserID < 0) {
            int errorCode = hCNetSDK.NET_DVR_GetLastError();
            log.error("登录异常:" + errorCode);
            log.debug(camera.getIp() + ":" + camera.getPort() + "登录失败");
            log.debug(camera.getIp() + ":" + camera.getPort() + "登录失败,错误码:"+errorCode);
            camera.setChanNum(0);
            camera.setLoginId(-1);
            camera.setState("0");
        } else {
            if (fExceptionCallBack == null) {
                fExceptionCallBack = new ExceptionCallBack();//异常回调
                //设置异常回调函数(可在回调函数中获取设备上下线状态等)
                if (!hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, null)) {
                    log.info("Set fExceptionCallBack function fail");
                    return;
                } else {
                    log.info("Set fExceptionCallBack function successfully!");
                }
            }
            if (GlobalVariable.loginMap.containsKey(camera.getId())) {
                GlobalVariable.loginMap.remove(camera.getId());
@@ -166,8 +136,9 @@
            //删除管理通道
            ardChannelService.deleteArdChannelByDeviceId(camera.getId());
            GlobalVariable.loginMap.put(camera.getId(), lUserID);
            log.debug(camera.getIp() + ":" + camera.getPort() + "登录成功");
            GlobalVariable.loginCameraMap.put(lUserID,camera);
            log.debug("Login Success [ " + camera.getIp() + ":" + camera.getPort() + " ]");
            camera.setLoginId(lUserID);
            camera.setState("1");
            camera.setChanNum((int) m_strDeviceInfo.struDeviceV30.byChanNum);
@@ -279,14 +250,12 @@
    @Override
    public void loginAll() {
        try {
            log.debug("加载lib完成!");
            ArdCameras ardCamera = new ArdCameras();
            ardCamera.setFactory("1");
            List<ArdCameras> ardCameras = ardCamerasService.selectArdCamerasListNoDataScope(ardCamera);
            for (ArdCameras camera : ardCameras) {
                Thread.sleep(500);
                //异步登录
                syncLogin(camera);
                //登录
                login(camera);
            }
        } catch (Exception ex) {
            log.error("初始化登录相机异常:" + ex.getMessage());
@@ -897,7 +866,6 @@
            log.error("控制失败,请稍后重试" + code);
            return new HashMap<>();
        }
    }
    /**
ard-work/src/main/resources/dynamic-lib-load.xml
@@ -1,41 +1,76 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dynamic-lib>
    <win64>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhplay</lib>
        <lib>RenderEngine</lib>
        <lib>ImageAlg</lib>
        <lib>Infra</lib>
        <lib>IvsDrawer</lib>
        <lib>StreamConvertor</lib>
    </win64>
    <win32>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhplay</lib>
        <lib>RenderEngine</lib>
        <lib>Infra</lib>
        <lib>ImageAlg</lib>
        <lib>StreamConvertor</lib>
    </win32>
    <linux64>
        <lib>avnetsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>StreamConvertor</lib>
    </linux64>
    <linux32>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
    </linux32>
    <mac64>
        <lib>avnetsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>StreamConvertor</lib>
    </mac64>
<?xml version="1.0" encoding="UTF-8" ?>
<dynamic-lib>
    <win64>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhplay</lib>
        <lib>RenderEngine</lib>
        <lib>ImageAlg</lib>
        <lib>Infra</lib>
        <lib>IvsDrawer</lib>
        <lib>StreamConvertor</lib>
        <lib>HCNetSDK</lib>
        <lib>HCCore</lib>
        <lib>GdiPlus</lib>
        <lib>hlog</lib>
        <lib>HmMerge</lib>
        <lib>hpr</lib>
        <lib>HXVA</lib>
        <lib>libcrypto-1_1-x64</lib>
        <lib>libmmd</lib>
        <lib>libssl-1_1-x64</lib>
        <lib>MP_Render</lib>
        <lib>NPQos</lib>
        <lib>OpenAL32</lib>
        <lib>PlayCtrl</lib>
        <lib>SuperRender</lib>
        <lib>YUVProcess</lib>
        <lib>zlib1</lib>
        <lib>HCNetSDKCom/AnalyzeData</lib>
        <lib>HCNetSDKCom/AudioIntercom</lib>
        <lib>HCNetSDKCom/AudioRender</lib>
        <lib>HCNetSDKCom/HCAlarm</lib>
        <lib>HCNetSDKCom/HCCoreDevCfg</lib>
        <lib>HCNetSDKCom/HCDisplay</lib>
        <lib>HCNetSDKCom/HCGeneralCfgMgr</lib>
        <lib>HCNetSDKCom/HCGeneralCfgMgr</lib>
        <lib>HCNetSDKCom/HCIndustry</lib>
        <lib>HCNetSDKCom/HCPlayBack</lib>
        <lib>HCNetSDKCom/HCPreview</lib>
        <lib>HCNetSDKCom/HCVoiceTalk</lib>
        <lib>HCNetSDKCom/libiconv2</lib>
        <lib>HCNetSDKCom/OpenAL32</lib>
        <lib>HCNetSDKCom/StreamTransClient</lib>
        <lib>HCNetSDKCom/SystemTransform</lib>
    </win64>
    <win32>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhplay</lib>
        <lib>RenderEngine</lib>
        <lib>Infra</lib>
        <lib>ImageAlg</lib>
        <lib>StreamConvertor</lib>
    </win32>
    <linux64>
        <lib>avnetsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>StreamConvertor</lib>
    </linux64>
    <linux32>
        <lib>avnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>dhnetsdk</lib>
    </linux32>
    <mac64>
        <lib>avnetsdk</lib>
        <lib>dhnetsdk</lib>
        <lib>dhconfigsdk</lib>
        <lib>StreamConvertor</lib>
    </mac64>
</dynamic-lib>
ard-work/src/main/resources/lib/win64/AudioRender.dll
Binary files differ
ard-work/src/main/resources/lib/win64/GdiPlus.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCCore.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDK.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/AnalyzeData.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/AudioIntercom.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/AudioRender.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCAlarm.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCAlarm.lib
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCCoreDevCfg.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCDisplay.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCGeneralCfgMgr.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCGeneralCfgMgr.lib
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCIndustry.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCPlayBack.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCPreview.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCPreview.lib
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/HCVoiceTalk.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/OpenAL32.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/StreamTransClient.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/SystemTransform.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HCNetSDKCom/libiconv2.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HXVA.dll
Binary files differ
ard-work/src/main/resources/lib/win64/HmMerge.dll
Binary files differ
ard-work/src/main/resources/lib/win64/ImageAlg.dll
Binary files differ
ard-work/src/main/resources/lib/win64/Infra.dll
Binary files differ
ard-work/src/main/resources/lib/win64/IvsDrawer.dll
Binary files differ
ard-work/src/main/resources/lib/win64/MP_Render.dll
Binary files differ
ard-work/src/main/resources/lib/win64/NPQos.dll
Binary files differ
ard-work/src/main/resources/lib/win64/OpenAL32.dll
copy from lib/hikDll/HCNetSDKCom/OpenAL32.dll copy to ard-work/src/main/resources/lib/win64/OpenAL32.dll Binary files differ
ard-work/src/main/resources/lib/win64/PlayCtrl.dll
Binary files differ
ard-work/src/main/resources/lib/win64/RenderEngine.dll
Binary files differ
ard-work/src/main/resources/lib/win64/StreamConvertor.dll
Binary files differ
ard-work/src/main/resources/lib/win64/SuperRender.dll
Binary files differ
ard-work/src/main/resources/lib/win64/YUVProcess.dll
Binary files differ
ard-work/src/main/resources/lib/win64/avnetsdk.dll
Binary files differ
ard-work/src/main/resources/lib/win64/dhconfigsdk.dll
Binary files differ
ard-work/src/main/resources/lib/win64/dhnetsdk.dll
Binary files differ
ard-work/src/main/resources/lib/win64/dhplay.dll
Binary files differ
ard-work/src/main/resources/lib/win64/hlog.dll
Binary files differ
ard-work/src/main/resources/lib/win64/hpr.dll
Binary files differ
ard-work/src/main/resources/lib/win64/libcrypto-1_1-x64.dll
Binary files differ
ard-work/src/main/resources/lib/win64/libmmd.dll
Binary files differ
ard-work/src/main/resources/lib/win64/libssl-1_1-x64.dll
Binary files differ
ard-work/src/main/resources/lib/win64/zlib1.dll
Binary files differ
lib/hikDll/ClientDemoDll/ReadMe.txt
文件已删除
lib/hikDll/ClientDemoDll/calib.dll
Binary files differ
lib/hikDll/ClientDemoDll/iconv.dll
Binary files differ
lib/hikDll/ClientDemoDll/libcrypto-1_1-x64.dll
Binary files differ
lib/hikDll/ClientDemoDll/libssl-1_1-x64.dll
Binary files differ
lib/hikDll/ClientDemoDll/libxml2.dll
Binary files differ
lib/hikDll/ClientDemoDll/zlib1.dll
Binary files differ
lib/hikDll/OpenAL32.dll
Binary files differ
lib/mediamtx/LICENSE
文件已删除
lib/mediamtx/ffmpeg.exe
Binary files differ
lib/mediamtx/mediamtx.exe
Binary files differ
lib/mediamtx/mediamtx.yml
文件已删除
lib/minio/minio.exe
Binary files differ
lib/redis/EventLog.dll
Binary files differ
lib/redis/Redis on Windows Release Notes.docx
Binary files differ
lib/redis/Redis on Windows.docx
Binary files differ
lib/redis/Windows Service Documentation.docx
Binary files differ
lib/redis/dump.rdb
Binary files differ
lib/redis/redis-benchmark.exe
Binary files differ
lib/redis/redis-benchmark.pdb
Binary files differ
lib/redis/redis-check-aof.exe
Binary files differ
lib/redis/redis-check-aof.pdb
Binary files differ
lib/redis/redis-cli.exe
Binary files differ
lib/redis/redis-cli.pdb
Binary files differ
lib/redis/redis-desktop-manager-0.9.3.817.exe
Binary files differ
lib/redis/redis-server.exe
Binary files differ
lib/redis/redis-server.pdb
Binary files differ
lib/redis/redis.windows-service.conf
文件已删除
lib/redis/redis.windows.conf
文件已删除
lib/webrtc/Procfile
文件已删除
lib/webrtc/config.json
文件已删除
lib/webrtc/html/Bunny.html
文件已删除
lib/webrtc/html/LICENSE
文件已删除
lib/webrtc/html/README.md
文件已删除
lib/webrtc/html/admin.html
文件已删除
lib/webrtc/html/apprtc.html
文件已删除
lib/webrtc/html/apprtc.json
文件已删除
lib/webrtc/html/help.html
文件已删除
lib/webrtc/html/htmlmapmarker.js
文件已删除
lib/webrtc/html/index.html
文件已删除
lib/webrtc/html/info.png
Binary files differ
lib/webrtc/html/janusconfig.js
文件已删除
lib/webrtc/html/janustest.html
文件已删除
lib/webrtc/html/janusvideoroom-element.js
文件已删除
lib/webrtc/html/janusvideoroom.html
文件已删除
lib/webrtc/html/janusvideoroom.js
文件已删除
lib/webrtc/html/jitsi.ico
Binary files differ
lib/webrtc/html/jitsiroom.html
文件已删除
lib/webrtc/html/jitsitest.html
文件已删除
lib/webrtc/html/jsdoc/JanusVideoRoom.html
文件已删除
lib/webrtc/html/jsdoc/WebRtcStreamer.html
文件已删除
lib/webrtc/html/jsdoc/XMPPVideoRoom.html
文件已删除
lib/webrtc/html/jsdoc/fonts/OpenSans-Bold-webfont.eot
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-Bold-webfont.svg
文件已删除
lib/webrtc/html/jsdoc/fonts/OpenSans-Bold-webfont.woff
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-BoldItalic-webfont.eot
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-BoldItalic-webfont.svg
文件已删除
lib/webrtc/html/jsdoc/fonts/OpenSans-BoldItalic-webfont.woff
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-Italic-webfont.eot
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-Italic-webfont.svg
文件已删除
lib/webrtc/html/jsdoc/fonts/OpenSans-Italic-webfont.woff
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-Light-webfont.eot
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-Light-webfont.svg
文件已删除
lib/webrtc/html/jsdoc/fonts/OpenSans-Light-webfont.woff
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-LightItalic-webfont.eot
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-LightItalic-webfont.svg
文件已删除
lib/webrtc/html/jsdoc/fonts/OpenSans-LightItalic-webfont.woff
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-Regular-webfont.eot
Binary files differ
lib/webrtc/html/jsdoc/fonts/OpenSans-Regular-webfont.svg
文件已删除
lib/webrtc/html/jsdoc/fonts/OpenSans-Regular-webfont.woff
Binary files differ
lib/webrtc/html/jsdoc/index.html
文件已删除
lib/webrtc/html/jsdoc/janusvideoroom.js.html
文件已删除
lib/webrtc/html/jsdoc/scripts/linenumber.js
文件已删除
lib/webrtc/html/jsdoc/scripts/prettify/Apache-License-2.0.txt
文件已删除
lib/webrtc/html/jsdoc/scripts/prettify/lang-css.js
文件已删除
lib/webrtc/html/jsdoc/scripts/prettify/prettify.js
文件已删除
lib/webrtc/html/jsdoc/styles/jsdoc-default.css
文件已删除
lib/webrtc/html/jsdoc/styles/prettify-jsdoc.css
文件已删除
lib/webrtc/html/jsdoc/styles/prettify-tomorrow.css
文件已删除
lib/webrtc/html/jsdoc/webrtcstreamer.js.html
文件已删除
lib/webrtc/html/jsdoc/xmppvideoroom.js.html
文件已删除
lib/webrtc/html/libs/EventEmitter.min.js
文件已删除
lib/webrtc/html/libs/adapter.min.js
文件已删除
lib/webrtc/html/libs/ag-grid.min.js
文件已删除
lib/webrtc/html/libs/blazeface
文件已删除
lib/webrtc/html/libs/body-pix
文件已删除
lib/webrtc/html/libs/coco-ssd
文件已删除
lib/webrtc/html/libs/deeplab
文件已删除
lib/webrtc/html/libs/jquery-3.5.1.min.js
文件已删除
lib/webrtc/html/libs/lib-jitsi-meet.min.js
文件已删除
lib/webrtc/html/libs/posenet
文件已删除
lib/webrtc/html/libs/strophe.disco.min.js
文件已删除
lib/webrtc/html/libs/strophe.jingle.sdp.js
文件已删除
lib/webrtc/html/libs/strophe.min.js
文件已删除
lib/webrtc/html/libs/strophe.muc.min.js
文件已删除
lib/webrtc/html/libs/tf-backend-wasm.js
文件已删除
lib/webrtc/html/libs/tfjs
文件已删除
lib/webrtc/html/libs/tfjs-backend-wasm-simd.wasm
Binary files differ
lib/webrtc/html/libs/tfjs-backend-wasm.wasm
Binary files differ
lib/webrtc/html/libs/whep-video.component.js
文件已删除
lib/webrtc/html/map.html
文件已删除
lib/webrtc/html/nav.css
文件已删除
lib/webrtc/html/sendstream.html
文件已删除
lib/webrtc/html/styles.css
文件已删除
lib/webrtc/html/tensorflow.js
文件已删除
lib/webrtc/html/webrtc-streamer-algo-element.js
文件已删除
lib/webrtc/html/webrtc-streamer-element.html
文件已删除
lib/webrtc/html/webrtc-streamer-element.js
文件已删除
lib/webrtc/html/webrtc-streamer-footer-element.js
文件已删除
lib/webrtc/html/webrtc-streamer-menu-element.js
文件已删除
lib/webrtc/html/webrtc-streamer-options-element.js
文件已删除
lib/webrtc/html/webrtc-streamer-selector-element.js
文件已删除
lib/webrtc/html/webrtc-streamer.html
文件已删除
lib/webrtc/html/webrtc.png
Binary files differ
lib/webrtc/html/webrtcconfig.js
文件已删除
lib/webrtc/html/webrtcstreamer.html
文件已删除
lib/webrtc/html/webrtcstreamer.js
文件已删除
lib/webrtc/html/whep.html
文件已删除
lib/webrtc/html/xmppconfig.js
文件已删除
lib/webrtc/html/xmppvideoroom.html
文件已删除
lib/webrtc/html/xmppvideoroom.js
文件已删除
lib/webrtc/webrtc-streamer.exe
Binary files differ
pom.xml
@@ -1,257 +1,257 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi</artifactId>
    <version>3.8.5</version>
    <name>ruoyi</name>
    <url>http://www.ruoyi.vip</url>
    <description>若依管理系统</description>
    <properties>
        <ruoyi.version>3.8.5</ruoyi.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
        <druid.version>1.2.15</druid.version>
        <bitwalker.version>1.21</bitwalker.version>
        <swagger.version>3.0.0</swagger.version>
        <kaptcha.version>2.3.3</kaptcha.version>
        <pagehelper.boot.version>1.4.6</pagehelper.boot.version>
        <fastjson.version>2.0.20</fastjson.version>
        <oshi.version>6.4.0</oshi.version>
        <commons.io.version>2.11.0</commons.io.version>
        <commons.fileupload.version>1.4</commons.fileupload.version>
        <commons.collections.version>3.2.2</commons.collections.version>
        <poi.version>4.1.2</poi.version>
        <velocity.version>2.3</velocity.version>
        <jwt.version>0.9.1</jwt.version>
        <okhttp.version>4.8.1</okhttp.version>
    </properties>
    <!-- 依赖声明 -->
    <dependencyManagement>
        <dependencies>
            <!-- SpringBoot的依赖配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.14</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- 解析客户端操作系统、浏览器等 -->
            <dependency>
                <groupId>eu.bitwalker</groupId>
                <artifactId>UserAgentUtils</artifactId>
                <version>${bitwalker.version}</version>
            </dependency>
            <!-- pagehelper 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
            </dependency>
            <!-- 获取系统信息 -->
            <dependency>
                <groupId>com.github.oshi</groupId>
                <artifactId>oshi-core</artifactId>
                <version>${oshi.version}</version>
            </dependency>
            <!-- Knife4j 增强Swagger文档 -->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>2.0.9</version>
            </dependency>
            <!-- Swagger3依赖 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-boot-starter</artifactId>
                <version>${swagger.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>io.swagger</groupId>
                        <artifactId>swagger-models</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- io常用工具类 -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons.io.version}</version>
            </dependency>
            <!-- 文件上传工具类 -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons.fileupload.version}</version>
            </dependency>
            <!-- excel工具 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!-- velocity代码生成使用模板 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity.version}</version>
            </dependency>
            <!-- collections工具类 -->
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${commons.collections.version}</version>
            </dependency>
            <!-- 阿里JSON解析器 -->
            <dependency>
                <groupId>com.alibaba.fastjson2</groupId>
                <artifactId>fastjson2</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!-- Token生成与解析-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jwt.version}</version>
            </dependency>
            <!-- 验证码 -->
            <dependency>
                <groupId>pro.fessional</groupId>
                <artifactId>kaptcha</artifactId>
                <version>${kaptcha.version}</version>
            </dependency>
            <!-- 定时任务-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-quartz</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 代码生成-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-generator</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 核心模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-framework</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 系统模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-system</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 通用工具-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-common</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- okhttp3-->
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp.version}</version>
            </dependency>
            <!-- ard业务模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ard-work</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <modules>
        <module>ruoyi-admin</module>
        <module>ruoyi-framework</module>
        <module>ruoyi-system</module>
        <module>ruoyi-quartz</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-common</module>
        <module>ard-work</module>
    </modules>
    <packaging>pom</packaging>
    <dependencies>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi</artifactId>
    <version>3.8.5</version>
    <name>ruoyi</name>
    <url>http://www.ruoyi.vip</url>
    <description>若依管理系统</description>
    <properties>
        <ruoyi.version>3.8.5</ruoyi.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
        <druid.version>1.2.15</druid.version>
        <bitwalker.version>1.21</bitwalker.version>
        <swagger.version>3.0.0</swagger.version>
        <kaptcha.version>2.3.3</kaptcha.version>
        <pagehelper.boot.version>1.4.6</pagehelper.boot.version>
        <fastjson.version>2.0.20</fastjson.version>
        <oshi.version>6.4.0</oshi.version>
        <commons.io.version>2.11.0</commons.io.version>
        <commons.fileupload.version>1.4</commons.fileupload.version>
        <commons.collections.version>3.2.2</commons.collections.version>
        <poi.version>4.1.2</poi.version>
        <velocity.version>2.3</velocity.version>
        <jwt.version>0.9.1</jwt.version>
        <okhttp.version>4.8.1</okhttp.version>
    </properties>
    <!-- 依赖声明 -->
    <dependencyManagement>
        <dependencies>
            <!-- SpringBoot的依赖配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.14</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- 解析客户端操作系统、浏览器等 -->
            <dependency>
                <groupId>eu.bitwalker</groupId>
                <artifactId>UserAgentUtils</artifactId>
                <version>${bitwalker.version}</version>
            </dependency>
            <!-- pagehelper 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
            </dependency>
            <!-- 获取系统信息 -->
            <dependency>
                <groupId>com.github.oshi</groupId>
                <artifactId>oshi-core</artifactId>
                <version>${oshi.version}</version>
            </dependency>
            <!-- Knife4j 增强Swagger文档 -->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>2.0.9</version>
            </dependency>
            <!-- Swagger3依赖 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-boot-starter</artifactId>
                <version>${swagger.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>io.swagger</groupId>
                        <artifactId>swagger-models</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- io常用工具类 -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons.io.version}</version>
            </dependency>
            <!-- 文件上传工具类 -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons.fileupload.version}</version>
            </dependency>
            <!-- excel工具 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!-- velocity代码生成使用模板 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity.version}</version>
            </dependency>
            <!-- collections工具类 -->
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${commons.collections.version}</version>
            </dependency>
            <!-- 阿里JSON解析器 -->
            <dependency>
                <groupId>com.alibaba.fastjson2</groupId>
                <artifactId>fastjson2</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!-- Token生成与解析-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jwt.version}</version>
            </dependency>
            <!-- 验证码 -->
            <dependency>
                <groupId>pro.fessional</groupId>
                <artifactId>kaptcha</artifactId>
                <version>${kaptcha.version}</version>
            </dependency>
            <!-- 定时任务-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-quartz</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 代码生成-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-generator</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 核心模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-framework</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 系统模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-system</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- 通用工具-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-common</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- okhttp3-->
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp.version}</version>
            </dependency>
            <!-- ard业务模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ard-work</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <modules>
        <module>ruoyi-admin</module>
        <module>ruoyi-framework</module>
        <module>ruoyi-system</module>
        <module>ruoyi-quartz</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-common</module>
        <module>ard-work</module>
    </modules>
    <packaging>pom</packaging>
    <dependencies>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>
ruoyi-admin/pom.xml
@@ -79,22 +79,22 @@
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <!-- 依赖包输出目录,将来不打进jar包里 -->
                            <outputDirectory>${project.build.directory}/jarLib</outputDirectory>
                            <excludeTransitive>false</excludeTransitive>
                            <stripVersion>false</stripVersion>
                            <includeScope>runtime</includeScope>
                        </configuration>
                    </execution>
                </executions>
<!--                <executions>-->
<!--                    <execution>-->
<!--                        <id>copy-dependencies</id>-->
<!--                        <phase>package</phase>-->
<!--                        <goals>-->
<!--                            <goal>copy-dependencies</goal>-->
<!--                        </goals>-->
<!--                        <configuration>-->
<!--                            &lt;!&ndash; 依赖包输出目录,将来不打进jar包里 &ndash;&gt;-->
<!--                            <outputDirectory>${project.build.directory}/jarLib</outputDirectory>-->
<!--                            <excludeTransitive>false</excludeTransitive>-->
<!--                            <stripVersion>false</stripVersion>-->
<!--                            <includeScope>runtime</includeScope>-->
<!--                        </configuration>-->
<!--                    </execution>-->
<!--                </executions>-->
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
@@ -102,14 +102,14 @@
                <version>2.1.1.RELEASE</version>
                <configuration>
                    <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
                    <mainClass>com.ruoyi.RuoYiApplication</mainClass>
                    <layout>ZIP</layout>
                    <includes>
                        <include>
                            <groupId>nothing</groupId>
                            <artifactId>nothing</artifactId>
                        </include>
                    </includes>
<!--                    <mainClass>com.ruoyi.RuoYiApplication</mainClass>-->
<!--                    <layout>ZIP</layout>-->
<!--                    <includes>-->
<!--                        <include>-->
<!--                            <groupId>nothing</groupId>-->
<!--                            <artifactId>nothing</artifactId>-->
<!--                        </include>-->
<!--                    </includes>-->
                </configuration>
                <executions>
                    <execution>
ruoyi-admin/src/main/resources/application-dev.yml
@@ -44,7 +44,7 @@
  level:
    authorize: info
    minio: info
    hikSdk: info
    hikSdk: debug
    dhSdk: debug
    stealAlarm: info
    websocket: info
ruoyi-admin/src/main/resources/logback.xml
@@ -1,326 +1,326 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
    <property name="log.path" value="./ardLog/logs"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 用户访问日志输出  -->
    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-user.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- Authorize日志输出  -->
    <appender name="authorize" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/authorize.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log.path}/authorize.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--hikSdk日志输出-->
    <appender name="hikSdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/hikSdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/hikSdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--dhSdk日志输出-->
    <appender name="dhSdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/dhSdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/dhSdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--dhSdk日志输出-->
    <appender name="sdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/sdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--minio日志输出-->
    <appender name="minio" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/minio.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/minio.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--盗电报警日志输出-->
    <appender name="stealAlarm" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/stealAlarm.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/stealAlarm.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--websocket报警日志输出-->
    <appender name="websocket" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/websocket.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/websocket.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--mqtt日志输出-->
    <appender name="mqtt" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/mqtt.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/mqtt.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--guideQueue日志输出-->
    <appender name="guideQueue" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/guideQueue.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/guideQueue.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--PatrolInspectionTask日志输出-->
    <appender name="patrolInspectionTask" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/patrolInspectionTask.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/patrolInspectionTask.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--融云日志输出-->
    <appender name="rongCloud" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/rongCloud.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/rongCloud.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--cmd命令日志输出-->
    <appender name="cmd" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/cmd.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/cmd.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--无人机日志输出-->
    <appender name="uav" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/uav.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/uav.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--三一车辆日志输出-->
    <appender name="sy" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sy.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/sy.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- 系统模块日志级别控制  -->
    <logger name="com.ruoyi" level="info"/>
    <!-- Spring日志级别控制  -->
    <logger name="org.springframework" level="warn"/>
    <!--控制台日志级别控制-->
    <root level="debug">
        <appender-ref ref="console"/>
    </root>
    <!--系统操作日志-->
    <root level="error">
        <appender-ref ref="file_info"/>
        <appender-ref ref="file_error"/>
    </root>
    <!--系统用户操作日志-->
    <logger name="sys-user" level="INFO">
        <appender-ref ref="sys-user"/>
    </logger>
    <!--hikSdk日志-->
    <logger name="hikSdk" level="INFO">
        <appender-ref ref="hikSdk"/>
    </logger>
    <!--dhSdk日志-->
    <logger name="dhSdk" level="INFO">
        <appender-ref ref="dhSdk"/>
    </logger>
    <!--sdk日志-->
    <logger name="sdk" level="INFO">
        <appender-ref ref="sdk"/>
    </logger>
    <!--mqtt日志-->
    <logger name="mqtt" level="INFO">
        <appender-ref ref="mqtt"/>
    </logger>
    <!--minio日志-->
    <logger name="minio" level="INFO">
        <appender-ref ref="minio"/>
    </logger>
    <!--cmd日志-->
    <logger name="cmd" level="INFO">
        <appender-ref ref="cmd"/>
    </logger>
    <!--uav日志-->
    <logger name="uav" level="INFO">
        <appender-ref ref="uav"/>
    </logger>
    <!--sy日志-->
    <logger name="sy" level="INFO">
        <appender-ref ref="sy"/>
    </logger>
    <!--rongCloud日志-->
    <logger name="rongCloud" level="INFO">
        <appender-ref ref="rongCloud"/>
    </logger>
    <!--patrolInspectionTask日志-->
    <logger name="patrolInspectionTask" level="INFO">
        <appender-ref ref="patrolInspectionTask"/>
    </logger>
    <!--authorize日志-->
    <logger name="authorize" level="INFO">
        <appender-ref ref="authorize"/>
    </logger>
    <!--guideQueue日志-->
    <logger name="guideQueue" level="INFO">
        <appender-ref ref="guideQueue"/>
    </logger>
    <!--stealAlarm日志-->
    <logger name="stealAlarm" level="INFO">
        <appender-ref ref="stealAlarm"/>
    </logger>
    <!--stealAlarm日志-->
    <logger name="websocket" level="INFO">
        <appender-ref ref="websocket"/>
    </logger>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
    <property name="log.path" value="./log"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 用户访问日志输出  -->
    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-user.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- Authorize日志输出  -->
    <appender name="authorize" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/authorize.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log.path}/authorize.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--hikSdk日志输出-->
    <appender name="hikSdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/hikSdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/hikSdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--dhSdk日志输出-->
    <appender name="dhSdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/dhSdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/dhSdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--dhSdk日志输出-->
    <appender name="sdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/sdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--minio日志输出-->
    <appender name="minio" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/minio.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/minio.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--盗电报警日志输出-->
    <appender name="stealAlarm" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/stealAlarm.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/stealAlarm.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--websocket报警日志输出-->
    <appender name="websocket" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/websocket.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/websocket.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--mqtt日志输出-->
    <appender name="mqtt" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/mqtt.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/mqtt.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--guideQueue日志输出-->
    <appender name="guideQueue" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/guideQueue.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/guideQueue.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--PatrolInspectionTask日志输出-->
    <appender name="patrolInspectionTask" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/patrolInspectionTask.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/patrolInspectionTask.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--融云日志输出-->
    <appender name="rongCloud" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/rongCloud.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/rongCloud.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--cmd命令日志输出-->
    <appender name="cmd" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/cmd.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/cmd.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--无人机日志输出-->
    <appender name="uav" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/uav.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/uav.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--三一车辆日志输出-->
    <appender name="sy" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sy.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/sy.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- 系统模块日志级别控制  -->
    <logger name="com.ruoyi" level="info"/>
    <!-- Spring日志级别控制  -->
    <logger name="org.springframework" level="warn"/>
    <!--控制台日志级别控制-->
    <root level="debug">
        <appender-ref ref="console"/>
    </root>
    <!--系统操作日志-->
    <root level="error">
        <appender-ref ref="file_info"/>
        <appender-ref ref="file_error"/>
    </root>
    <!--系统用户操作日志-->
    <logger name="sys-user" level="INFO">
        <appender-ref ref="sys-user"/>
    </logger>
    <!--hikSdk日志-->
    <logger name="hikSdk" level="INFO">
        <appender-ref ref="hikSdk"/>
    </logger>
    <!--dhSdk日志-->
    <logger name="dhSdk" level="INFO">
        <appender-ref ref="dhSdk"/>
    </logger>
    <!--sdk日志-->
    <logger name="sdk" level="INFO">
        <appender-ref ref="sdk"/>
    </logger>
    <!--mqtt日志-->
    <logger name="mqtt" level="INFO">
        <appender-ref ref="mqtt"/>
    </logger>
    <!--minio日志-->
    <logger name="minio" level="INFO">
        <appender-ref ref="minio"/>
    </logger>
    <!--cmd日志-->
    <logger name="cmd" level="INFO">
        <appender-ref ref="cmd"/>
    </logger>
    <!--uav日志-->
    <logger name="uav" level="INFO">
        <appender-ref ref="uav"/>
    </logger>
    <!--sy日志-->
    <logger name="sy" level="INFO">
        <appender-ref ref="sy"/>
    </logger>
    <!--rongCloud日志-->
    <logger name="rongCloud" level="INFO">
        <appender-ref ref="rongCloud"/>
    </logger>
    <!--patrolInspectionTask日志-->
    <logger name="patrolInspectionTask" level="INFO">
        <appender-ref ref="patrolInspectionTask"/>
    </logger>
    <!--authorize日志-->
    <logger name="authorize" level="INFO">
        <appender-ref ref="authorize"/>
    </logger>
    <!--guideQueue日志-->
    <logger name="guideQueue" level="INFO">
        <appender-ref ref="guideQueue"/>
    </logger>
    <!--stealAlarm日志-->
    <logger name="stealAlarm" level="INFO">
        <appender-ref ref="stealAlarm"/>
    </logger>
    <!--stealAlarm日志-->
    <logger name="websocket" level="INFO">
        <appender-ref ref="websocket"/>
    </logger>
</configuration>