unknown 3 lat temu
commit
d8805cb388
84 zmienionych plików z 13490 dodań i 0 usunięć
  1. 293 0
      .gitignore
  2. 186 0
      pom.xml
  3. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCAlarm.so
  4. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCCoreDevCfg.so
  5. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCDisplay.so
  6. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCGeneralCfgMgr.so
  7. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCIndustry.so
  8. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCPlayBack.so
  9. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCPreview.so
  10. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libHCVoiceTalk.so
  11. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libStreamTransClient.so
  12. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libSystemTransform.so
  13. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libanalyzedata.so
  14. BIN
      resourcesFile/cameraDll/linux/HCNetSDKCom/libiconv2.so
  15. 12 0
      resourcesFile/cameraDll/linux/HCNetSDK_Log_Switch.xml
  16. BIN
      resourcesFile/cameraDll/linux/libAudioRender.so
  17. BIN
      resourcesFile/cameraDll/linux/libHCCore.so
  18. BIN
      resourcesFile/cameraDll/linux/libNPQos.so
  19. BIN
      resourcesFile/cameraDll/linux/libPlayCtrl.so
  20. BIN
      resourcesFile/cameraDll/linux/libSuperRender.so
  21. BIN
      resourcesFile/cameraDll/linux/libcrypto.so
  22. BIN
      resourcesFile/cameraDll/linux/libcrypto.so.1.0.0
  23. BIN
      resourcesFile/cameraDll/linux/libhcnetsdk.so
  24. BIN
      resourcesFile/cameraDll/linux/libhpr.so
  25. BIN
      resourcesFile/cameraDll/linux/libssl.so
  26. BIN
      resourcesFile/cameraDll/windows/AudioRender.dll
  27. BIN
      resourcesFile/cameraDll/windows/EagleEyeRender.dll
  28. BIN
      resourcesFile/cameraDll/windows/GdiPlus.dll
  29. BIN
      resourcesFile/cameraDll/windows/HCCore.dll
  30. BIN
      resourcesFile/cameraDll/windows/HCNetSDK.dll
  31. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/AnalyzeData.dll
  32. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/AudioIntercom.dll
  33. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.dll
  34. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.lib
  35. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCCoreDevCfg.dll
  36. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCDisplay.dll
  37. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.dll
  38. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.lib
  39. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCIndustry.dll
  40. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCPlayBack.dll
  41. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.dll
  42. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.lib
  43. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCVoiceTalk.dll
  44. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/OpenAL32.dll
  45. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/StreamTransClient.dll
  46. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/SystemTransform.dll
  47. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/libiconv2.dll
  48. BIN
      resourcesFile/cameraDll/windows/HXVA.dll
  49. BIN
      resourcesFile/cameraDll/windows/MP_Render.dll
  50. BIN
      resourcesFile/cameraDll/windows/NPQos.dll
  51. BIN
      resourcesFile/cameraDll/windows/PlayCtrl.dll
  52. BIN
      resourcesFile/cameraDll/windows/SuperRender.dll
  53. BIN
      resourcesFile/cameraDll/windows/YUVProcess.dll
  54. BIN
      resourcesFile/cameraDll/windows/hlog.dll
  55. BIN
      resourcesFile/cameraDll/windows/hpr.dll
  56. BIN
      resourcesFile/cameraDll/windows/libeay32.dll
  57. BIN
      resourcesFile/cameraDll/windows/libmmd.dll
  58. BIN
      resourcesFile/cameraDll/windows/ssleay32.dll
  59. 11 0
      src/main/java/com/persagy/MainApplication.java
  60. 15 0
      src/main/java/com/persagy/cameractl/conf/AllStaticConfig.java
  61. 84 0
      src/main/java/com/persagy/cameractl/conf/CameraApiConfig.java
  62. 53 0
      src/main/java/com/persagy/cameractl/conf/MyParamConfig.java
  63. 23 0
      src/main/java/com/persagy/cameractl/conf/ServerConfig.java
  64. 23 0
      src/main/java/com/persagy/cameractl/conf/TcpConfig.java
  65. 178 0
      src/main/java/com/persagy/cameractl/controller/HelloController.java
  66. 43 0
      src/main/java/com/persagy/cameractl/init/SystemInit.java
  67. 4924 0
      src/main/java/com/persagy/cameractl/service/HCNetSDKLinux.java
  68. 3574 0
      src/main/java/com/persagy/cameractl/service/HCNetSDKWindows.java
  69. 1351 0
      src/main/java/com/persagy/cameractl/service/HaiKMainLinux.java
  70. 1396 0
      src/main/java/com/persagy/cameractl/service/HaiKMainWindows.java
  71. 389 0
      src/main/java/com/persagy/cameractl/service/HkCameraExecuteApi.java
  72. 50 0
      src/main/java/com/persagy/cameractl/service/PtzMain.java
  73. 103 0
      src/main/java/com/persagy/cameractl/utils/Camera.java
  74. 12 0
      src/main/java/com/persagy/cameractl/utils/CameraLoop.java
  75. 63 0
      src/main/java/com/persagy/cameractl/utils/CmdStreamThread.java
  76. 62 0
      src/main/java/com/persagy/cameractl/utils/EnumTools.java
  77. 44 0
      src/main/java/com/persagy/cameractl/utils/JsonTools.java
  78. 24 0
      src/main/java/com/persagy/cameractl/utils/MimeCamera.java
  79. 134 0
      src/main/java/com/persagy/cameractl/utils/OtherTools.java
  80. 24 0
      src/main/java/com/persagy/cameractl/utils/ResultClass.java
  81. 70 0
      src/main/java/com/persagy/cameractl/utils/ResultTools.java
  82. 310 0
      src/main/java/com/persagy/cameractl/utils/StringTools.java
  83. 38 0
      src/main/java/com/persagy/cameractl/utils/TimerInterval.java
  84. 1 0
      src/main/resources/application.yml

+ 293 - 0
.gitignore

@@ -0,0 +1,293 @@
+# Created by https://www.gitignore.io/api/git,java,maven,macos,linux,windows,eclipse,netbeans,java-web,code-java,intellij+all
+# Edit at https://www.gitignore.io/?templates=git,java,maven,macos,linux,windows,eclipse,netbeans,java-web,code-java,intellij+all
+
+### Code-Java ###
+# Language Support for Java(TM) by Red Hat extension for Visual Studio Code - https://marketplace.visualstudio.com/items?itemName=redhat.java
+
+.project
+.classpath
+factoryConfiguration.json
+
+### Eclipse ###
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# CDT- autotools
+.autotools
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+# Annotation Processing
+.apt_generated/
+
+# Scala IDE specific (Scala & Java development for Eclipse)
+.cache-main
+.scala_dependencies
+.worksheet
+
+### Eclipse Patch ###
+# Eclipse Core
+
+# JDT-specific (Eclipse Java Development Tools)
+
+# Annotation Processing
+.apt_generated
+
+.sts4-cache/
+
+### Git ###
+# Created by git for backups. To disable backups in Git:
+# $ git config --global mergetool.keepBackup false
+*.orig
+
+# Created by git when using merge tools for conflicts
+*.BACKUP.*
+*.BASE.*
+*.LOCAL.*
+*.REMOTE.*
+*_BACKUP_*.txt
+*_BASE_*.txt
+*_LOCAL_*.txt
+*_REMOTE_*.txt
+
+### Intellij+all ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij+all Patch ###
+# Ignores the whole .idea folder and all .iml files
+# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
+
+.idea/
+
+# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
+
+*.iml
+modules.xml
+.idea/misc.xml
+*.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+### Java-Web ###
+## ignoring target file
+target/
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Maven ###
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+
+### NetBeans ###
+**/nbproject/private/
+**/nbproject/Makefile-*.mk
+**/nbproject/Package-*.bash
+build/
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk

+ 186 - 0
pom.xml

@@ -0,0 +1,186 @@
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.persagy</groupId>
+	<artifactId>persagy-camera-haikang</artifactId>
+	<version>0.0.1</version>
+	<description>摄像头监控</description>
+
+	<repositories>
+		<repository>
+			<id>nexus-aliyun</id>
+			<name>Nexus aliyun</name>
+			<layout>default</layout>
+			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+		</repository>
+		<repository>
+			<id>SagaCloud</id>
+			<name>SagaCloud</name>
+			<url>http://47.93.132.139:8081/nexus/content/groups/public/</url>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+		</repository>
+	</repositories>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+		<resources>
+			<resource>
+				<directory>src/main/resources</directory>
+				<includes>
+					<include>**/*</include>
+					<include>*.yml</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>src/main/resources/jar</directory>
+				<targetPath>BOOT-INF/lib/</targetPath>
+				<includes>
+					<include>**/*.jar</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>src/main/resources</directory>
+				<targetPath>BOOT-INF/classes/</targetPath>
+			</resource>
+		</resources>
+	</build>
+
+	<parent>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-parent</artifactId>
+		<version>2.2.6.RELEASE</version>
+	</parent>
+
+	<properties>
+		<java.version>1.8</java.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<!-- 引入模板引擎 -->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-thymeleaf</artifactId>
+		</dependency>
+		<!-- 启用不严格检查html -->
+		<dependency>
+			<groupId>net.sourceforge.nekohtml</groupId>
+			<artifactId>nekohtml</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-configuration-processor</artifactId>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>com.sun.jna</groupId>
+			<artifactId>jna</artifactId>
+			<version>1.0</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/src/main/resources/jar/jna.jar</systemPath>
+		</dependency>
+
+		<dependency>
+			<groupId>com.sun.jna.examples</groupId>
+			<artifactId>examples</artifactId>
+			<version>1.0</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/src/main/resources/jar/examples.jar</systemPath>
+		</dependency>
+
+
+		<dependency>
+			<groupId>org.java-websocket</groupId>
+			<artifactId>Java-WebSocket</artifactId>
+			<version>1.4.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.hikvision.ga</groupId>
+			<artifactId>artemis-http-client</artifactId>
+			<version>1.1.3</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-beanutils</groupId>
+			<artifactId>commons-beanutils</artifactId>
+			<version>1.8.3</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-collections</groupId>
+			<artifactId>commons-collections</artifactId>
+			<version>3.2.1</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>2.5</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-logging</groupId>
+			<artifactId>commons-logging</artifactId>
+			<version>1.1.1</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.kordamp.ezmorph</groupId>
+			<artifactId>ezmorph</artifactId>
+			<version>2.0.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>net.sf.json-lib</groupId>
+			<artifactId>json-lib</artifactId>
+			<version>2.4</version>
+			<classifier>jdk15</classifier>
+		</dependency>
+
+		<dependency>
+			<groupId>cn.hutool</groupId>
+			<artifactId>hutool-core</artifactId>
+			<version>5.6.3</version>
+		</dependency>
+		
+		<dependency>
+		  <groupId>dom4j</groupId>
+		  <artifactId>dom4j</artifactId>
+		  <version>1.6.1</version>
+		</dependency>
+		
+		<dependency>
+            <groupId>jaxen</groupId>
+            <artifactId>jaxen</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+
+
+	</dependencies>
+
+
+</project>

BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCAlarm.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCCoreDevCfg.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCDisplay.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCGeneralCfgMgr.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCIndustry.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCPlayBack.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCPreview.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libHCVoiceTalk.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libStreamTransClient.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libSystemTransform.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libanalyzedata.so


BIN
resourcesFile/cameraDll/linux/HCNetSDKCom/libiconv2.so


+ 12 - 0
resourcesFile/cameraDll/linux/HCNetSDK_Log_Switch.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="GB2312"?>
+<SdkLocal>
+	<SdkLog>
+        <logLevel>3</logLevel><!--req, 1-ERROR, 2-DEBUG, 3-INFO-->
+        <logDirectory>./SDKLOG/</logDirectory><!--the end of the string must be '/'-->
+        <autoDelete>true</autoDelete><!--true: There are less than 10 files in the directory, it will be auto deleted by sdk when the files are more than 10; false: No upper limit to the number of log files-->
+    </SdkLog>
+	<HeartbeatCfg>
+		<Interval>120</Interval> <!-- 心跳时间间隔,单位秒,等于0,使用默认值120s,取值范围为[30, 120] 小于30s,间隔为30s,大于120s,间隔为120s-->
+		<Count>1</Count> 	<!-- 触发异常回调需要心跳交互异常的次数,等于0,使用默认值1次-->
+	</HeartbeatCfg>
+</SdkLocal>

BIN
resourcesFile/cameraDll/linux/libAudioRender.so


BIN
resourcesFile/cameraDll/linux/libHCCore.so


BIN
resourcesFile/cameraDll/linux/libNPQos.so


BIN
resourcesFile/cameraDll/linux/libPlayCtrl.so


BIN
resourcesFile/cameraDll/linux/libSuperRender.so


BIN
resourcesFile/cameraDll/linux/libcrypto.so


BIN
resourcesFile/cameraDll/linux/libcrypto.so.1.0.0


BIN
resourcesFile/cameraDll/linux/libhcnetsdk.so


BIN
resourcesFile/cameraDll/linux/libhpr.so


BIN
resourcesFile/cameraDll/linux/libssl.so


BIN
resourcesFile/cameraDll/windows/AudioRender.dll


BIN
resourcesFile/cameraDll/windows/EagleEyeRender.dll


BIN
resourcesFile/cameraDll/windows/GdiPlus.dll


BIN
resourcesFile/cameraDll/windows/HCCore.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDK.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/AnalyzeData.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/AudioIntercom.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.lib


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCCoreDevCfg.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCDisplay.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.lib


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCIndustry.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCPlayBack.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.lib


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCVoiceTalk.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/OpenAL32.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/StreamTransClient.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/SystemTransform.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/libiconv2.dll


BIN
resourcesFile/cameraDll/windows/HXVA.dll


BIN
resourcesFile/cameraDll/windows/MP_Render.dll


BIN
resourcesFile/cameraDll/windows/NPQos.dll


BIN
resourcesFile/cameraDll/windows/PlayCtrl.dll


BIN
resourcesFile/cameraDll/windows/SuperRender.dll


BIN
resourcesFile/cameraDll/windows/YUVProcess.dll


BIN
resourcesFile/cameraDll/windows/hlog.dll


BIN
resourcesFile/cameraDll/windows/hpr.dll


BIN
resourcesFile/cameraDll/windows/libeay32.dll


BIN
resourcesFile/cameraDll/windows/libmmd.dll


BIN
resourcesFile/cameraDll/windows/ssleay32.dll


+ 11 - 0
src/main/java/com/persagy/MainApplication.java

@@ -0,0 +1,11 @@
+package com.persagy;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MainApplication {
+	public static void main(String[] args) {
+		SpringApplication.run(MainApplication.class, args);
+	}
+}

+ 15 - 0
src/main/java/com/persagy/cameractl/conf/AllStaticConfig.java

@@ -0,0 +1,15 @@
+package com.persagy.cameractl.conf;
+
+public class AllStaticConfig {
+	// 69解码器IP
+	public static String decodeDeviceIp;
+
+	// 69解码器端口号
+	public static int decodeDevicePort = 8000;
+
+	// 69解码器用户名
+	public static String decodeDeviceUserName = "admin";
+
+	// 69解码器密码
+	public static String decodeDevicePassword;
+}

+ 84 - 0
src/main/java/com/persagy/cameractl/conf/CameraApiConfig.java

@@ -0,0 +1,84 @@
+package com.persagy.cameractl.conf;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CameraApiConfig {
+	@Value("${hk-config.host}")
+	private String hkApiHost;
+	
+	@Value("${hk-config.appKey}")
+	private String hkApiKey;
+	
+	@Value("${hk-config.appSecret}")
+	private String hkApiSecret;
+	
+	@Value("${hk-config.decodeDeviceIp}")
+	private String decodeDeviceIp;
+	
+	@Value("${hk-config.decodeDeviceUserName}")
+	private String decodeDeviceUserName;
+	
+	@Value("${hk-config.decodeDevicePassword}")
+	private String decodeDevicePassword;
+	
+	@Value("${hk-config.decodeDevicePort}")
+	private int decodeDevicePort;
+
+	public String getHkApiHost() {
+		return hkApiHost;
+	}
+
+	public void setHkApiHost(String hkApiHost) {
+		this.hkApiHost = hkApiHost;
+	}
+
+	public String getHkApiKey() {
+		return hkApiKey;
+	}
+
+	public void setHkApiKey(String hkApiKey) {
+		this.hkApiKey = hkApiKey;
+	}
+
+	public String getHkApiSecret() {
+		return hkApiSecret;
+	}
+
+	public void setHkApiSecret(String hkApiSecret) {
+		this.hkApiSecret = hkApiSecret;
+	}
+
+	public String getDecodeDeviceIp() {
+		return decodeDeviceIp;
+	}
+
+	public void setDecodeDeviceIp(String decodeDeviceIp) {
+		this.decodeDeviceIp = decodeDeviceIp;
+	}
+
+	public String getDecodeDeviceUserName() {
+		return decodeDeviceUserName;
+	}
+
+	public void setDecodeDeviceUserName(String decodeDeviceUserName) {
+		this.decodeDeviceUserName = decodeDeviceUserName;
+	}
+
+	public String getDecodeDevicePassword() {
+		return decodeDevicePassword;
+	}
+
+	public void setDecodeDevicePassword(String decodeDevicePassword) {
+		this.decodeDevicePassword = decodeDevicePassword;
+	}
+
+	public int getDecodeDevicePort() {
+		return decodeDevicePort;
+	}
+
+	public void setDecodeDevicePort(int decodeDevicePort) {
+		this.decodeDevicePort = decodeDevicePort;
+	}
+}

+ 53 - 0
src/main/java/com/persagy/cameractl/conf/MyParamConfig.java

@@ -0,0 +1,53 @@
+package com.persagy.cameractl.conf;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "myself-param")
+public class MyParamConfig {
+	 private String paramStr;
+	 private Integer paramInt;
+	 private Double paramDouble;
+	 private List<String> paramList;
+	 private Map<String, String> maps;
+	public String getParamStr() {
+		return paramStr;
+	}
+	public void setParamStr(String paramStr) {
+		this.paramStr = paramStr;
+	}
+	public Integer getParamInt() {
+		return paramInt;
+	}
+	public void setParamInt(Integer paramInt) {
+		this.paramInt = paramInt;
+	}
+	public Double getParamDouble() {
+		return paramDouble;
+	}
+	public void setParamDouble(Double paramDouble) {
+		this.paramDouble = paramDouble;
+	}
+	public List<String> getParamList() {
+		return paramList;
+	}
+	public void setParamList(List<String> paramList) {
+		this.paramList = paramList;
+	}
+	public Map<String, String> getMaps() {
+		return maps;
+	}
+	public void setMaps(Map<String, String> maps) {
+		this.maps = maps;
+	}
+	@Override
+	public String toString() {
+		return "MyParamConfig [paramStr=" + paramStr + ", paramInt=" + paramInt + ", paramDouble=" + paramDouble
+				+ ", paramList=" + paramList + ", maps=" + maps + "]";
+	}
+	
+}

+ 23 - 0
src/main/java/com/persagy/cameractl/conf/ServerConfig.java

@@ -0,0 +1,23 @@
+package com.persagy.cameractl.conf;
+
+import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Value;
+
+@Component
+public class ServerConfig {
+	 @Value("${server.port}")
+	 private int serverPort;
+	 @Value("${server.servlet.context-path}")
+	 private String contextPath;
+	 
+	 public String getUrl() {
+//        InetAddress address = null;
+//        try {
+//            address = InetAddress.getLocalHost();
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//        return address.getHostAddress() +":"+this.serverPort+this.contextPath;
+		 return this.serverPort+this.contextPath;
+    }
+}

+ 23 - 0
src/main/java/com/persagy/cameractl/conf/TcpConfig.java

@@ -0,0 +1,23 @@
+package com.persagy.cameractl.conf;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "tcp-config")
+public class TcpConfig {
+	private int port;
+
+	public int getPort() {
+		return port;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
+	}
+
+	@Override
+	public String toString() {
+		return "TcpConfig [port=" + port + "]";
+	}
+}

+ 178 - 0
src/main/java/com/persagy/cameractl/controller/HelloController.java

@@ -0,0 +1,178 @@
+package com.persagy.cameractl.controller;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import com.persagy.cameractl.conf.MyParamConfig;
+import com.persagy.cameractl.utils.ResultTools;
+import com.persagy.cameractl.utils.StringTools;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.service.PtzMain;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.MimeCamera;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.cameractl.service.HkCameraExecuteApi;
+
+@Controller
+@CrossOrigin
+public class HelloController {
+	@Autowired
+	private MyParamConfig myParamConfig;
+	@Autowired
+	private HkCameraExecuteApi hkCameraExecuteApi;
+
+	@RequestMapping(value = "/hello", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
+	public @ResponseBody String hello() {
+		System.out.println(myParamConfig);
+		return ResultTools.successResult();
+	}
+
+	@RequestMapping(value = "/hello/{name}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
+	public @ResponseBody String helloName(@PathVariable("name") String name) {
+
+		return ResultTools.errorResult(name);
+	}
+
+	/*
+	 * 摄像头操作接口(底层调用SDK),包括:摄像头控制、回放。客户端回放流程为:客户端先调用该接口,成功后再调用vplayf接口播放MP4
+	 * opertype为control时,参数:command、cameraIp、cameraPort、userName、password、channel、speed
+	 * 
+	 * opertype为playback时,参数:cameraIp、cameraPort、userName、password、channel、startDateStr、endDateStr
+	 * 
+	 * opertype为toup时的参数:
+	 * 	layoutCode(one、left-up-one、right-down-one、right-up-one、left-down-one、multi-one)、
+	 * 	videoSourceArr(MimeCamera[])
+	 * 
+	 * opertype为lx时的参数:
+	 * 	layoutCode(one、left-up-one、right-down-one、right-up-one、left-down-one、multi-one)
+	 * 	cameraLoopArr(CameraLoop[])
+	 */
+	@RequestMapping(value = "/sdk/{opertype}", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
+	public @ResponseBody String ptzOperation(@PathVariable("opertype") String operType, @RequestBody Camera _camera) {
+		PtzMain pcControlMain = new PtzMain();
+		ResultClass result = pcControlMain.ptzOper(_camera, operType);
+		switch (String.valueOf(result.name)) {
+		// 调用成功
+		case "true":
+			return ResultTools.dataResult(result.resultData);
+		// 调用失败
+		default:
+			return ResultTools.errorResult(result.reason);
+		}
+	}
+
+	/*
+	 * 请求视频文件接口
+	 */
+	@RequestMapping(value = "/vplayf/{token}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
+	public @ResponseBody void vplay(@PathVariable("token") String token, HttpServletResponse response) {
+		String filePath = OtherTools.getVideoFilePathByT(token);
+//		File mp4File = new File(filePath);
+//		if (!mp4File.exists())
+//			return ResultTools.errorResult("文件不存在");
+//		Map<String, String> dataMap = new HashMap<String, String>();
+//		dataMap.put("path", filePath);
+//		return ResultTools.dataResult(dataMap);
+
+		if (filePath.equals(""))
+			return;
+		try {
+			File mp4File = new File(filePath);
+			if (!mp4File.exists())
+				return;
+			FileInputStream inputStream = new FileInputStream(filePath);
+			byte[] data = new byte[inputStream.available()];
+			inputStream.read(data);
+			String diskfilename = "_.mp4";
+			response.setContentType("video/mp4");
+			response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"");
+//			             System.out.println("data.length " + data.length);
+			response.setContentLength(data.length);
+			response.setHeader("Content-Range", "" + Integer.valueOf(data.length - 1));
+			response.setHeader("Accept-Ranges", "bytes");
+			response.setHeader("Etag", "W/\"" + StringTools.getUUID() + "\"");
+			OutputStream os = response.getOutputStream();
+
+			os.write(data);
+			// 先声明的流后关掉!
+			os.flush();
+			os.close();
+			inputStream.close();
+
+		} catch (Exception e) {
+		}
+	}
+
+	/*
+	 * 摄像头视频实时播放接口
+	 */
+	@RequestMapping(value = "/realplay", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
+	public @ResponseBody String realPlay(@RequestBody Camera _camera) {
+		PtzMain pcControlMain = new PtzMain();
+		ResultClass playResult = pcControlMain.realPlay(_camera);
+		switch (String.valueOf(playResult.name)) {
+		// 调用成功
+		case "true":
+			return ResultTools.successResult();
+		// 调用失败
+		default:
+			return ResultTools.errorResult(playResult.reason);
+		}
+	}
+
+	/*
+	 * 调用软件平台接口,根据摄像头监控点位获取预览流url、回放取流、控制
+	 * operType: preview 预览	playback 回放	points 查询点位信息	control	云台控制	token 获取access_token
+	 * 			 dianshiq 获取电视墙大屏信息      other 支持传入接口名称和参数,方便调试
+	 * 	预览参数:
+	 * 		cameraIndexCode(监控点编码,必传)、streamType(码流类型,可不传)、protocol(取流协议或格式,可不传,暂时只支持hls)、transcode(是否转码,可不传)、resolution(分辨率,可不传)、bitrate(比特率,可不传)、videotype(视频格式)
+	 *	回放参数:
+	 *		cameraIndexCode(监控点编码,必传)、protocol(取流协议或格式,可不传,支持hls、rtsp,为rtsp时:会把rtsp视频流转成mp4再返回给客户端)、startDateStr(开始时间,必传)、endDateStr(结束时间,必传)、transcode(是否转码,可不传)、resolution(分辨率,可不传)、bitrate(比特率,可不传)
+	 *	查询点位信息参数:
+	 *		pageNo(页码,必传)、pageSize(每页条数,必传)
+	 *	云台控制参数:
+	 *		cameraIndexCode(监控点编码,必传)、command(命令,必传)、speed(速度,可不传)
+	 *	获取access_token参数:
+	 *		无
+	 *	获取电视墙大屏信息参数:
+	 *		无
+	 *	other 根据传入接口名称来调用对应的海康软件平台接口,参数:
+	 *		url 调用的海康开放平台接口名称,不需要加 /artemis/api/
+	 *		paramStr 传给海康开放平台接口的参数,格式:{"pageNo":1,"pageSize":1000}
+	 */
+	@RequestMapping(value = "/vision/{opertype}", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
+	public @ResponseBody String hikvisionOper(@PathVariable("opertype") String operType, @RequestBody Camera camera) {
+		ResultClass executeResult = operType.equals("preview") ? hkCameraExecuteApi.GetCameraPreviewURL(camera)
+				: operType.equals("playback") ? hkCameraExecuteApi.GetCameraPlayBackURL(camera)
+						: operType.equals("control") ? hkCameraExecuteApi.PtzControllingMain(camera)
+								: operType.equals("points") ? hkCameraExecuteApi.GetCameraPointsByPage(camera)
+										: operType.equals("token") ? hkCameraExecuteApi.GetAccessToken(camera)
+												: operType.equals("dianshiq")
+														? hkCameraExecuteApi.GetDianshiQiang(camera)
+														: operType.equals("other")
+																? hkCameraExecuteApi.GetOtherInfo(camera)
+																: new ResultClass(false, "非法请求");
+		switch (String.valueOf(executeResult.name)) {
+		// 调用成功
+		case "true":
+			return ResultTools.dataResult(executeResult.resultData);
+		// 调用失败
+		default:
+			return ResultTools.errorResult(executeResult.reason);
+		}
+	}
+}

+ 43 - 0
src/main/java/com/persagy/cameractl/init/SystemInit.java

@@ -0,0 +1,43 @@
+package com.persagy.cameractl.init;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+import com.persagy.cameractl.conf.CameraApiConfig;
+import com.persagy.cameractl.conf.ServerConfig;
+import com.persagy.cameractl.utils.TimerInterval;
+
+@Component
+@Order(1)
+public class SystemInit implements ApplicationRunner {
+	Logger log = LoggerFactory.getLogger(SystemInit.class);
+
+	@Autowired
+	private ServerConfig serverConfig;
+	
+	@Autowired
+	private CameraApiConfig cameraApiConfig;
+
+	@Override
+	public void run(ApplicationArguments args) throws Exception {
+		AllStaticConfig.decodeDeviceIp=cameraApiConfig.getDecodeDeviceIp();
+		AllStaticConfig.decodeDeviceUserName=cameraApiConfig.getDecodeDeviceUserName();
+		AllStaticConfig.decodeDevicePassword=cameraApiConfig.getDecodeDevicePassword();
+		AllStaticConfig.decodeDevicePort=cameraApiConfig.getDecodeDevicePort();
+		
+		log.info("SystemInit start");
+		System.out.println("端口号:"+serverConfig.getUrl());
+		log.info("SystemInit ...");
+		log.info("SystemInit end");
+
+		//启动定时清除文件的定时器
+		TimerInterval.startClearFileTimer();
+	}
+
+}

Plik diff jest za duży
+ 4924 - 0
src/main/java/com/persagy/cameractl/service/HCNetSDKLinux.java


Plik diff jest za duży
+ 3574 - 0
src/main/java/com/persagy/cameractl/service/HCNetSDKWindows.java


Plik diff jest za duży
+ 1351 - 0
src/main/java/com/persagy/cameractl/service/HaiKMainLinux.java


Plik diff jest za duży
+ 1396 - 0
src/main/java/com/persagy/cameractl/service/HaiKMainWindows.java


+ 389 - 0
src/main/java/com/persagy/cameractl/service/HkCameraExecuteApi.java

@@ -0,0 +1,389 @@
+package com.persagy.cameractl.service;
+
+import com.hikvision.artemis.sdk.ArtemisHttpUtil;
+import com.hikvision.artemis.sdk.config.ArtemisConfig;
+import com.persagy.cameractl.conf.CameraApiConfig;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.CmdStreamThread;
+import com.persagy.cameractl.utils.EnumTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.cameractl.utils.JsonTools;
+import com.persagy.cameractl.utils.OtherTools;
+import cn.hutool.core.date.DateUtil;
+
+import java.io.File;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import net.sf.json.JSONObject;
+
+@Component
+public class HkCameraExecuteApi {
+	Logger logger = LoggerFactory.getLogger(HkCameraExecuteApi.class);
+	@Autowired
+	private CameraApiConfig cameraApiConfig;
+
+	/**
+	 * STEP2:设置OpenAPI接口的上下文
+	 */
+	final String ARTEMIS_PATH = "/artemis/api/";
+
+	/*
+	 * 解析返回结果
+	 * */
+	private ResultClass parseResult(String resultStr) {
+		ResultClass resultClass = new ResultClass();
+		resultClass.name = false;
+		try {
+			if (resultStr == null || resultStr.equals("")) {
+				resultClass.reason = "结果为空";
+				return resultClass;
+			}
+			// org.springframework.boot.configurationprocessor.json.JSONObject resultMap=new
+			// org.springframework.boot.configurationprocessor.json.JSONObject(resultStr);
+			Map<String, Object> mapResult = JsonTools.str2Map(resultStr);
+			String msgStr = String.valueOf(mapResult.get("msg"));
+			if (msgStr == null || !msgStr.equals("success")) {
+				resultClass.reason = "错误码:" + String.valueOf(mapResult.get("code")) + ",错误原因:"
+						+ String.valueOf(mapResult.get("msg"));
+				return resultClass;
+			}
+			resultClass.name = true;
+			resultClass.resultData = mapResult.get("data");
+			return resultClass;
+		} catch (Exception e) {
+			logger.error("海康中心平台返回结果非法:" + resultStr);
+			resultClass.reason = "海康中心平台返回结果非法,请查看后台日志";
+			return resultClass;
+		}
+	};
+
+	/*
+	 * 发送请求并解析返回结果
+	 * */
+	private ResultClass SendRequest(String url, String paramString) {
+		/**
+		 * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数.
+		 */
+		ArtemisConfig.host = cameraApiConfig.getHkApiHost(); // artemis网关服务器ip端口
+		ArtemisConfig.appKey = cameraApiConfig.getHkApiKey(); // 秘钥appkey
+		ArtemisConfig.appSecret = cameraApiConfig.getHkApiSecret();// 秘钥appSecret
+
+		/**
+		 * STEP3:设置接口的URI地址
+		 */
+		String previewURLsApi = ARTEMIS_PATH + url;
+		Map<String, String> path = new HashMap<String, String>(2) {
+			/**
+			 * 
+			 */
+			private static final long serialVersionUID = 1L;
+
+			{
+				put("https://", previewURLsApi);// 根据现场环境部署确认是http还是https
+			}
+		};
+
+		/**
+		 * STEP4:设置参数提交方式
+		 */
+		String contentType = "application/json";
+		/**
+		 * STEP6:调用接口
+		 */
+		String result = ArtemisHttpUtil.doPostStringArtemis(path, paramString, null, null, contentType, null);// post请求application/json类型参数
+		return parseResult(result);
+	};
+
+	/*
+	 * 根据监控点获取预览流
+	 */
+	public ResultClass GetCameraPreviewURL(Camera hkCamera) {
+		try {
+			String url = "video/v2/cameras/previewURLs";
+
+			/**
+			 * STEP5:组装请求参数
+			 */
+			JSONObject jsonBody = new JSONObject();
+			jsonBody.put("cameraIndexCode", hkCamera.cameraIndexCode);
+			jsonBody.put("streamType", hkCamera.streamType);
+			jsonBody.put("protocol", hkCamera.protocol);
+			// 传输协议(传输层协议),0:UDP 1:TCP 默认是TCP 注:GB28181 2011及以前版本只支持UDP传输
+//			jsonBody.put("transmode", 1);
+			String expandStr = "transcode=" + hkCamera.transcode + "&resolution=" + hkCamera.resolution + "&bitrate="
+					+ hkCamera.bitrate + "&videotype=" + hkCamera.videotype;
+			jsonBody.put("expand", expandStr);
+			String body = jsonBody.toString();
+			return SendRequest(url, body);
+		} catch (Exception e) {
+			logger.error("海康调用实时预览API出错:", e);
+			ResultClass resultClass = new ResultClass(false, "海康调用实时预览API出错");
+			return resultClass;
+		}
+
+	}
+
+	/*
+	 * 根据监控点获取回放流
+	 */
+	public ResultClass GetCameraPlayBackURL(Camera hkCamera) {
+		try {
+			String reqUrl = "video/v2/cameras/playbackURLs";
+			/**
+			 * STEP5:组装请求参数
+			 * 因为香港置地返回的回放rtsp流总是在剩余大概15秒的时候卡顿,所以传过去的结束时间要加30秒,所以ffmpeg命令里要用-t控制实际读取时长
+			 */
+
+			Date dateStart = DateUtil.parse(hkCamera.startDateStr);
+			long startMillSeconds = dateStart.getTime();
+
+			Date dateEnd = DateUtil.parse(hkCamera.endDateStr);
+			long endMillSeconds = dateEnd.getTime();
+
+			// 先求得真实的回放时长
+			long temp = endMillSeconds - startMillSeconds;
+			long hourCount = 0;
+			long minuteCount = 0;
+			long secondCount = temp / 1000;
+			long millSecondCount = temp % 1000;
+			// 到了分钟级
+			if (secondCount >= 60) {
+				minuteCount = secondCount / 60;
+				secondCount = secondCount % 60;
+				// 到了小时级
+				if (minuteCount >= 60) {
+					hourCount = minuteCount / 60;
+					minuteCount = minuteCount % 60;
+				}
+			}
+
+			long endMillSeconds2 = endMillSeconds + 30 * 1000;
+			Date enDate2 = DateUtil.date(endMillSeconds2);
+			String endString2 = DateUtil.format(enDate2, "yyyy-MM-dd HH:mm:ss");
+
+			JSONObject jsonBody = new JSONObject();
+			jsonBody.put("cameraIndexCode", hkCamera.cameraIndexCode);
+			jsonBody.put("protocol", hkCamera.protocol);
+			jsonBody.put("beginTime", hkCamera.startDateStr.replace(" ", "T") + ".000+08:00");
+			jsonBody.put("endTime", endString2.replace(" ", "T") + ".000+08:00");
+
+			// 传输协议(传输层协议),0:UDP 1:TCP 默认是TCP 注:GB28181 2011及以前版本只支持UDP传输
+//			jsonBody.put("transmode", 1);
+			String expandStr = "transcode=" + hkCamera.transcode + "&resolution=" + hkCamera.resolution + "&bitrate="
+					+ hkCamera.bitrate + "&videotype=" + hkCamera.videotype;
+			jsonBody.put("expand", expandStr);
+			String body = jsonBody.toString();
+
+			ResultClass resultClass = SendRequest(reqUrl, body);
+//			return resultClass;
+			// hls格式回放时,直接返回
+//			if (hkCamera.protocol.equals("hls"))
+//				return resultClass;
+			/*
+			 * 如果不是hls格式,那么即为rtsp格式,此时需抓取rtsp流并转成mp4
+			 * */
+			// 调用失败直接返回
+			if (!resultClass.name)
+				return resultClass;
+			String resultDataStr = JsonTools.obj2Str(resultClass.resultData);
+			Map<String, Object> resultDataMap = JsonTools.str2Map(resultDataStr);
+			String videoUrl = String.valueOf(resultDataMap.get("url"));
+			if (videoUrl == null || videoUrl.equals(""))
+				return new ResultClass(false, "未获取到视频源地址");
+
+			String playFilePath = OtherTools.getVideoFilePath();
+			if (playFilePath.equals("")) {
+				return new ResultClass(false, "回放文件名称生成失败");
+			}
+			// 抓取视频流转为页面上可播放的MP4
+			Runtime run = Runtime.getRuntime();
+			/*
+			 * stimeout、rw_timeout的单位为微秒  1秒=1000000微秒
+			 * 因为香港置地返回的回放rtsp流总是在剩余大概15秒的时候卡顿,所以传过去的结束时间要加30秒,所以ffmpeg命令里要用-t控制实际读取时长
+			 * */
+			String timeDuration = hourCount + ":" + minuteCount + ":" + secondCount
+					+ (millSecondCount > 0 ? "." + millSecondCount : "");
+			String cmdStr = hkCamera.protocol.equals("hls")
+					? ("ffmpeg -i \"" + videoUrl + "\" -c copy -y \"" + playFilePath + "\"")
+					: ("ffmpeg -t " + timeDuration + " -rtsp_transport tcp -i \"" + videoUrl + "\" -y \"" + playFilePath
+							+ "\"");
+			Process p = run.exec(cmdStr);
+
+			// 读取标准输入流、输出流,防止进程阻塞
+			CmdStreamThread cmdStreamThread = new CmdStreamThread(p.getInputStream(), p.getErrorStream());
+
+			int retCode = p.waitFor();
+			p.destroy();
+			if (retCode == 0) {
+//		    	正常转换结束
+				File mp4File = new File(playFilePath);
+				String playFileName = mp4File.getName();
+				String token = OtherTools.getMp4NamePrefix(playFileName);
+				String url = OtherTools.playMp4RootUrl + token;
+				Map<String, String> dataMap = new HashMap<String, String>();
+				dataMap.put("url", url);
+				dataMap.put("videoUrl", videoUrl);
+				return new ResultClass(true, dataMap);
+			} else {
+//		    	转换出错
+				String errStr = cmdStreamThread.errString != null ? cmdStreamThread.errString
+						: cmdStreamThread.outString;
+				logger.error("ffmpeg抓取rtsp转为mp4时失败,错误信息:" + errStr);
+				return new ResultClass(false, "ffmpeg抓取rtsp转为mp4时失败");
+			}
+		} catch (Exception e) {
+			logger.error("海康调用回调API出错:", e);
+			ResultClass resultClass = new ResultClass(false, "海康调用回调API出错");
+			return resultClass;
+		}
+
+	}
+
+	/*
+	 * 控制命令入口
+	 * */
+	public ResultClass PtzControllingMain(Camera hkCamera) {
+		// 开始控制命令
+		ResultClass startResultClass = PtzControlling(hkCamera, 0);
+		// 控制命令执行成功后要调用停止命令
+		if (startResultClass.name) {
+			// 停止控制
+			ResultClass endResultClass = PtzControlling(hkCamera, 1);
+			return endResultClass;
+		}
+		return startResultClass;
+	}
+
+	/*
+	 * 根据监控点进行云台控制
+	 */
+	private ResultClass PtzControlling(Camera hkCamera, int action) {
+		try {
+			String url = "video/v1/ptzs/controlling";
+
+			/**
+			 * STEP5:组装请求参数
+			 */
+			JSONObject jsonBody = new JSONObject();
+			jsonBody.put("cameraIndexCode", hkCamera.cameraIndexCode);
+			// 0 开始 1 停止
+			jsonBody.put("action", action);
+
+			int sdkCommandIndex = EnumTools.listSdkCommand.indexOf(hkCamera.command);
+			if (sdkCommandIndex == -1)
+				return new ResultClass(false, "无效的控制命令");
+			String commandStr = EnumTools.arrHkvisionCommand[sdkCommandIndex];
+
+			jsonBody.put("command", commandStr);
+			jsonBody.put("speed", hkCamera.speed);
+			String body = jsonBody.toString();
+
+			ResultClass resultClass = SendRequest(url, body);
+			return resultClass;
+		} catch (Exception e) {
+			String str = action == 0 ? "开始时" : "停止时";
+			logger.error("海康调用控制API," + str + "出错:", e);
+			ResultClass resultClass = new ResultClass(false, "海康调用控制API" + str + "出错");
+			return resultClass;
+		}
+
+	}
+
+	/* 分页获取监控点 */
+	public ResultClass GetCameraPointsByPage(Camera hkCamera) {
+		try {
+			String url = "resource/v1/cameras";
+
+			/**
+			 * STEP5:组装请求参数
+			 */
+			JSONObject jsonBody = new JSONObject();
+			jsonBody.put("pageNo", hkCamera.pageNo);
+			jsonBody.put("pageSize", hkCamera.pageSize);
+			String body = jsonBody.toString();
+
+			return SendRequest(url, body);
+		} catch (Exception e) {
+			logger.error("海康调用分页获取监控点API出错:", e);
+			ResultClass resultClass = new ResultClass(false, "海康调用分页获取监控点API出错");
+			return resultClass;
+		}
+
+	}
+
+	/*
+	 * 获取access_token
+	 */
+	public ResultClass GetAccessToken(Camera hkCamera) {
+		try {
+			String url = "v1/oauth/token";
+
+			/**
+			 * STEP5:组装请求参数
+			 */
+			JSONObject jsonBody = new JSONObject();
+			String body = jsonBody.toString();
+			return SendRequest(url, body);
+		} catch (Exception e) {
+			logger.error("海康调用access_token API出错:", e);
+			ResultClass resultClass = new ResultClass(false, "海康调用access_token API出错");
+			return resultClass;
+		}
+
+	}
+
+	/*
+	 * 获取电视墙大屏信息
+	 */
+	public ResultClass GetDianshiQiang(Camera hkCamera) {
+		try {
+			String url = "tvms/v1/tvwall/allResources";
+
+			/**
+			 * STEP5:组装请求参数
+			 */
+			JSONObject jsonBody = new JSONObject();
+			String body = jsonBody.toString();
+			ResultClass resultClass = SendRequest(url, body);
+			return resultClass;
+		} catch (Exception e) {
+			logger.error("海康调用电视墙大屏API出错:", e);
+			ResultClass resultClass = new ResultClass(false, "海康调用电视墙大屏API出错");
+			return resultClass;
+		}
+
+	}
+
+	/*
+	 * 传入接口名称和参数,方便客户端调用测试
+	 */
+	public ResultClass GetOtherInfo(Camera hkCamera) {
+		try {
+			String paramStr = "";
+			if (hkCamera.paramStr != null && !"".equals(hkCamera.paramStr)) {
+				JSONObject jsonBody = new JSONObject();
+				Map<String, Object> tempMap = JsonTools.str2Map(hkCamera.paramStr);
+
+				for (Map.Entry<String, Object> entry : tempMap.entrySet()) {
+					jsonBody.put(entry.getKey(), entry.getValue());
+				}
+				paramStr = jsonBody.toString();
+			}
+
+			ResultClass resultClass = SendRequest(hkCamera.url, paramStr);
+			return resultClass;
+		} catch (Exception e) {
+			logger.error("海康" + hkCamera.url + "出错:", e);
+			ResultClass resultClass = new ResultClass(false, "海康调用" + hkCamera.url + "出错");
+			return resultClass;
+		}
+
+	}
+
+}

+ 50 - 0
src/main/java/com/persagy/cameractl/service/PtzMain.java

@@ -0,0 +1,50 @@
+package com.persagy.cameractl.service;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.cameractl.utils.EnumTools.OperatingSystem;
+import com.persagy.cameractl.utils.OtherTools;
+
+/*
+ * 摄像头相关调用的入口
+ * */
+public class PtzMain {
+	/*
+	 * 摄像头操作接口,包括:摄像头控制、回放
+	 */
+	public ResultClass ptzOper(Camera _camera, String operType) {
+		OperatingSystem systemName = OtherTools.getSystemName();
+		if (operType.equals("toup") || operType.equals("lx")) {
+			_camera.cameraIp = AllStaticConfig.decodeDeviceIp;
+			_camera.userName = AllStaticConfig.decodeDeviceUserName;
+			_camera.password = AllStaticConfig.decodeDevicePassword;
+			_camera.cameraPort = AllStaticConfig.decodeDevicePort;
+		}
+		switch (systemName) {
+		case windows:
+			HaiKMainWindows hKM = new HaiKMainWindows(_camera);
+			return operType.equals("control") ? hKM.controlMain()
+					: operType.equals("playback") ? hKM.playBackMain()
+							: operType.equals("getwall") ? hKM.getTvWallInfo()
+									: operType.equals("toup") ? hKM.touP()
+											: operType.equals("lx") ? hKM.lunx()
+											: OtherTools.executeErr("无效的操作类型");
+		default:
+			HaiKMainLinux hKMLinux = new HaiKMainLinux(_camera);
+			return operType.equals("control") ? hKMLinux.controlMain()
+					: operType.equals("playback") ? hKMLinux.playBackMain() 
+							: operType.equals("toup") ? hKMLinux.touP()
+									: operType.equals("lx") ? hKMLinux.lunx(): OtherTools.executeErr("无效的操作类型");
+		}
+	};
+
+	/*
+	 * 摄像头实时播放入口
+	 */
+	public ResultClass realPlay(Camera _camera) {
+		HaiKMainWindows hKM = new HaiKMainWindows(_camera);
+		return hKM.realPlayMain();
+	};
+
+}

+ 103 - 0
src/main/java/com/persagy/cameractl/utils/Camera.java

@@ -0,0 +1,103 @@
+package com.persagy.cameractl.utils;
+
+/*
+ * 摄像头对象
+ * */
+public class Camera {
+	// 通道号  1~32表示模拟通道,9000系列混合型DVR和NVR等设备的IP通道从33开始(即程序用的通道号为33+通道号-1)。回放、实时播放、控制使用
+	public int channel;
+	
+	// 码流类型 0:主码流 	1:子码流 	2:第三码流 参数不填,默认为子码流
+	public int streamType=1;
+
+	// 命令类型,参见EnumTool.listSdkCommand
+	public String command;
+
+	// 开始还是停止 true 开始 false 停止
+	public Boolean dwStop = true;
+
+	// 移动速度,调用硬件SDK时值范围1~7,默认7;调用软件平台时值范围为1~100,默认50。此处给默认值50,在调用SDK入口处判断大于7的时候,给7
+	public int speed = 50;
+
+	// 摄像头IP
+	public String cameraIp;
+
+	// 摄像头服务端口号
+	public int cameraPort=8000;
+
+	// 登录用户名
+	public String userName="admin";
+
+	// 登录密码
+	public String password;
+
+	// 开始时间,用于回放。格式:2021-03-01 15:02:11
+	public String startDateStr;
+	
+	// 结束时间,用于回放。格式:2021-03-01 15:02:11
+	public String endDateStr;
+	
+	//监控点编码
+	public String cameraIndexCode;
+	
+	/*
+	 * 布局编码,取值范围:
+	 * 	one(只有一个窗口)、left-up-one(六个窗口,左上角是大窗口)、
+	 * 	right-down-one(六个窗口,右下角是大窗口)、right-up-one(六个窗口,右上角是大窗口)、
+	 * 	left-down-one(六个窗口,左下角是大窗口)、multi-one(九宫格窗口)
+	 * */
+	public String layoutCode;
+	
+	//视频墙数据源数组,每一项均为MimeCamera,数组的顺序和窗口顺序保持一致,投屏时使用
+	public MimeCamera[] videoSourceArr;
+	
+	//轮巡时使用:轮巡数据源
+	public CameraLoop[] cameraLoopArr;
+	
+	/*-----------------------------以下为调用海康软件平台需要的参数------------------------------*/
+	
+	/*
+	 * 取流协议(应用层协议,调用开放平台时需要) 值: 
+	 * 	hik:HIK私有协议,使用视频SDK进行播放时,传入此类型; 
+	 * 	rtsp:RTSP协议; 
+	 * 	rtmp:RTMP协议;
+	 * 	hls:HLS协议(HLS协议只支持海康SDK协议、EHOME协议、ONVIF协议接入的设备;只支持H264视频编码和AAC音频编码)。
+	 * 参数不填,默认为hls协议
+	 */
+	public String protocol = "hls";
+	
+	//(调用开放平台时需要) 0	不转码	1	组件转码	2	设备转码,仅支持分辨率、比特率、帧率转码参数进行转码。默认1
+	public int transcode = 1;
+	
+	/*
+	 * 分辨率,取值范围:
+	 * 组件转码:QCIF(176*144),QVAG(320*240),CIF(352*288),2CIF(704*288),D1(720*576),720P(
+	 * 1280*720),1080P(1920*1080);
+	 * 设备转码:QCIF(176*144)、NCIF(320*240)、CIF(352*288)、VGA(640*480)、HCIF(704*288)、FCIF
+	 * (704*576)、D1(960*576)、720P(1280*720)、920P(1280*960)、1080P(1920*1080)、AUTO
+	 * 默认:CIF
+	 */
+	public String resolution = "CIF";
+
+	/*
+	 * 比特率,取值范围: 组件转码:最小值是128Kbps,最大值是8192Kbps 设备转码:最小值是128Kbps,最大值是16384Kbps 默认:512
+	 */
+	public int bitrate = 512;
+
+	/*
+	 * 视频编码格式,值:h264
+	 */
+	public String videotype = "h264";
+	
+	//页码,根据分页获取监控点位时使用
+	public int pageNo;
+	
+	//每页的条数,根据分页获取监控点位时使用
+	public int pageSize;
+	
+	//接口名称,方便客户端调用
+	public String url;
+	
+	//接口所需要的参数,格式:{"pageNo":1,"pageSize":1000}
+	public String paramStr;
+}

+ 12 - 0
src/main/java/com/persagy/cameractl/utils/CameraLoop.java

@@ -0,0 +1,12 @@
+package com.persagy.cameractl.utils;
+
+public class CameraLoop {
+	// 轮巡时间,单位秒,默认10秒
+	public int loopTime = 10;
+
+	// 窗口ID,从1开始,依次+1
+	public int windowId;
+
+	// 视频数据源数组,每一项均为MimeCamera
+	public MimeCamera[] videoSourceArr;
+}

+ 63 - 0
src/main/java/com/persagy/cameractl/utils/CmdStreamThread.java

@@ -0,0 +1,63 @@
+package com.persagy.cameractl.utils;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/*
+ * 新线程里读取cmd命令的输入流和错误流以免造成进程堵塞
+ * */
+public class CmdStreamThread {
+	private BufferedReader inputBfr = null;
+	private BufferedReader errBfr = null;
+	public String outString;
+	public String errString;
+
+	public CmdStreamThread(InputStream inputStream,InputStream errStream) {
+		this.inputBfr = new BufferedReader(new InputStreamReader(inputStream));
+		this.errBfr = new BufferedReader(new InputStreamReader(errStream));
+		new Thread(new InputStreamThread()).start();
+		new Thread(new ErrStreamThread()).start();
+	}
+	
+	/*
+	 * 读取输入流
+	 * */
+	class InputStreamThread implements Runnable {
+		@Override
+		public void run() {
+			try {
+				String s;
+				StringBuilder sb = new StringBuilder();
+				while ((s = inputBfr.readLine()) != null) {
+					sb.append(s);
+				}
+				inputBfr.close();
+				outString = sb.toString();
+			} catch (Exception e) {
+				outString = e.getMessage();
+			}
+		}
+	};
+	
+	/*
+	 * 读取错误流
+	 * */
+	class ErrStreamThread implements Runnable {
+		@Override
+		public void run() {
+			try {
+				String s;
+				StringBuilder sb = new StringBuilder();
+				while ((s = errBfr.readLine()) != null) {
+					sb.append(s);
+				}
+				errBfr.close();
+				errString = sb.toString();
+			} catch (Exception e) {
+				errString = e.getMessage();
+			}
+		}
+	};
+
+}

+ 62 - 0
src/main/java/com/persagy/cameractl/utils/EnumTools.java

@@ -0,0 +1,62 @@
+package com.persagy.cameractl.utils;
+
+import java.util.ArrayList;
+
+public class EnumTools {
+	/*------------------定义操作系统----------------------*/
+	public enum OperatingSystem {
+		linux, windows, other;
+	}
+
+	/*------------------定义摄像头操作命令类型,SDK的命令,也是浏览器端传过来的命令----------------------*/
+	public static ArrayList<String> listSdkCommand=new ArrayList<String>() {/**
+		 * 
+		 */
+		private static final long serialVersionUID = 1L;
+
+	{
+		// 焦距变大,即倍率变大
+		add("ZOOM_IN");
+		// 焦距变小,即倍率变小
+				add("ZOOM_OUT");
+				// 焦点前调,即调焦++
+				add("FOCUS_NEAR");
+				// 焦点后调,即调焦--
+				add("FOCUS_FAR");
+				// 光圈扩大
+				add("IRIS_OPEN");
+				// 光圈缩小
+				add("IRIS_CLOSE");
+				// 上仰
+				add("TILT_UP");
+				// 下俯
+				add("TILT_DOWN");
+				// 左转
+				add("PAN_LEFT");
+				// 右转
+				add("PAN_RIGHT");
+				// 左上转动或(上仰和左转)
+				add("UP_LEFT");
+				// 左下转动或(下俯和左转)
+				add("DOWN_LEFT");
+				// 右上转动或(上仰和右转)
+				add("UP_RIGHT");
+				// 右下转动或(下俯和右转)
+				add("DOWN_RIGHT");
+	}};
+	/*------------------定义摄像头操作命令类型,SDK的命令对应的编码----------------------*/
+	public static int[] arrSdkCommandCode=new int[] {11,12,13,14,15,16,21,22,23,24,25,27,26,28};
+	
+	/*------------------定义摄像头操作命令类型,软件接口的命令----------------------*/
+	public static String[] arrHkvisionCommand=new String[] {
+			"ZOOM_IN","ZOOM_OUT","FOCUS_NEAR","FOCUS_FAR","IRIS_ENLARGE",
+			"IRIS_REDUCE","UP","DOWN","LEFT","RIGHT","LEFT_UP","LEFT_DOWN",
+			"RIGHT_UP","RIGHT_DOWN",""};
+	
+	/*------------------定义控制失败编码----------------------*/
+	public enum ControlFailedCode {
+		// 初始化失败
+		init_failed
+	}
+
+}

+ 44 - 0
src/main/java/com/persagy/cameractl/utils/JsonTools.java

@@ -0,0 +1,44 @@
+package com.persagy.cameractl.utils;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class JsonTools {
+	private static ObjectMapper mapper = new ObjectMapper();
+	
+	public static String obj2Str(Object obj) throws JsonProcessingException {
+		return null != obj ? mapper.writeValueAsString(obj) : null;
+	}
+	
+	public static Map<String, Object> str2Map(String str) throws Exception {
+		if(null == str) {
+			return null;
+		}
+		
+		return mapper.readValue(str, new TypeReference<Map<String, Object>>(){});
+	}
+	
+	public static JsonNode str2JsonNode(String str) throws IOException {
+		if(null != str) {
+			return mapper.readTree(str);
+		}
+		return null;
+	}
+	
+	public static <T> T jsonStr2Obj(String jsonStr, Class<T> clz) throws Exception {
+		if(null == jsonStr) {
+			return null;
+		}
+		
+		return mapper.readValue(jsonStr, clz);
+	}
+	
+	public static JsonNode newInstance() throws IOException {
+		return mapper.readTree("{}");
+	}
+}

+ 24 - 0
src/main/java/com/persagy/cameractl/utils/MimeCamera.java

@@ -0,0 +1,24 @@
+package com.persagy.cameractl.utils;
+
+/*
+ * 大屏的数据源里需要摄像头IP、端口号、通道、用户名、密码,所以单独出类MimeCamera
+ * */
+public class MimeCamera {
+	// 摄像头IP
+	public String cameraIp;
+
+	// 摄像头服务端口号
+	public int cameraPort = 8000;
+
+	// 通道号 1~32表示模拟通道,9000系列混合型DVR和NVR等设备的IP通道从33开始(即程序用的通道号为33+通道号-1)。回放、实时播放、控制使用
+	public int channel;
+
+	// 登录用户名
+	public String userName = "admin";
+
+	// 登录密码
+	public String password;
+
+	// 码流类型 0:主码流 ;	1:子码流 
+	public int streamType = 1;
+}

+ 134 - 0
src/main/java/com/persagy/cameractl/utils/OtherTools.java

@@ -0,0 +1,134 @@
+package com.persagy.cameractl.utils;
+
+import com.persagy.cameractl.utils.EnumTools.OperatingSystem;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OtherTools {
+	static Logger logger = LoggerFactory.getLogger(OtherTools.class);
+//	播放mp4文件的url根地址
+	public static String playMp4RootUrl = "/vplayf/";
+	public static String dahuaDllPath = "";
+	public static String fileSperator = File.separator;
+
+	/*
+	 * 获取系统的操作系统类型
+	 */
+	public static OperatingSystem getSystemName() {
+		String os = System.getProperty("os.name").toLowerCase();
+		if (os.indexOf(OperatingSystem.windows.toString()) > -1)
+			return OperatingSystem.windows;
+		else if (os.indexOf(OperatingSystem.linux.toString()) > -1)
+			return OperatingSystem.linux;
+		return OperatingSystem.other;
+	}
+
+	/*
+	 * 获取摄像头厂家dll的路径
+	 */
+	public static String getDllPath(String dllName) {
+		String newPath = "";
+		OperatingSystem systemName = OtherTools.getSystemName();
+		switch (systemName) {
+		case linux:
+			newPath = dllName;
+			break;
+		default:
+			String dllPath = "./resourcesFile/cameraDll/" + systemName.toString() + "/" + dllName;
+			try {
+				File file1 = new File(dllPath);
+				newPath = file1.getCanonicalPath();
+			} catch (Exception e) {
+				// TODO: handle exception
+			}
+		}
+		return newPath;
+	}
+
+	/* 操作失败时,拼接错误信息 */
+	public static String joinErrStr(String errCode, String prefix) {
+		return (prefix != null && prefix != "" ? prefix + "," : "") + "厂家返回错误码:" + errCode;
+	}
+
+	public static String getVideoFilePath() {
+		String token = StringTools.getUUID();
+		return OtherTools.getVideoFilePathByT(token);
+	};
+
+	public static String getVideoFilePathByT(String token) {
+		try {
+			String playFileName = OtherTools.getMp4FullName(token);
+			String playFileDir = OtherTools.getVideoFileDir();
+			return playFileDir + fileSperator + playFileName;
+		} catch (Exception e) {
+			logger.error(e.getMessage());
+			return "";
+		}
+	};
+
+	public static String getVideoFileDir() {
+		String dllPath = "./resourcesFile/tempVideo";
+		String newPath = "";
+		try {
+			File file1 = new File(dllPath);
+			newPath = file1.getCanonicalPath();
+		} catch (Exception e) {
+			// TODO: handle exception
+		}
+
+		return newPath;
+	}
+
+	public static String getVideoFilePath(Camera _camera) {
+		try {
+			String startTimeStr = _camera.startDateStr.replaceAll("[-:\\s]", "");
+			String endTimeStr = _camera.endDateStr.replaceAll("[-:\\s]", "");
+			String ipStr = _camera.cameraIp.replace(".", "_");
+			String playFileName = OtherTools.getMp4FullName(startTimeStr + "_" + endTimeStr + "_" + _camera.channel);
+			String playFileDir = getVideoFileDir() + fileSperator + ipStr;
+			return playFileDir + fileSperator + playFileName;
+		} catch (Exception e) {
+			logger.error(e.getMessage());
+			return "";
+		}
+	};
+
+	public static String getMp4FullName(String prefix) {
+		return prefix + ".mp4";
+	};
+
+	public static String getMp4NamePrefix(String fullName) {
+		return fullName.substring(0, fullName.lastIndexOf("."));
+	};
+
+	public static ResultClass executeErr(String reason) {
+		return new ResultClass(false, reason);
+	};
+
+	public static ResultClass executeSuccess(Object resultData) {
+		return new ResultClass(true, resultData);
+	};
+
+	/**
+	 * 读取标准输入流、输出流,防止进程阻塞
+	 */
+	public static String consumeInputStream(InputStream istream) {
+		try {
+			BufferedReader br = new BufferedReader(new InputStreamReader(istream));
+			String s;
+			StringBuilder sb = new StringBuilder();
+			while ((s = br.readLine()) != null) {
+				sb.append(s);
+			}
+			return sb.toString();
+		} catch (Exception e) {
+			return e.getMessage();
+		}
+	}
+}

+ 24 - 0
src/main/java/com/persagy/cameractl/utils/ResultClass.java

@@ -0,0 +1,24 @@
+package com.persagy.cameractl.utils;
+
+public class ResultClass {
+	public boolean name;
+	public String reason;
+	public Object resultData;
+
+	public ResultClass() {
+	};
+
+	public ResultClass(boolean _name, String _reason) {
+		this(_name, _reason, null);
+	};
+	
+	public ResultClass(boolean _name, Object _resultData) {
+		this(_name, "", _resultData);
+	};
+
+	public ResultClass(boolean _name, String _reason, Object _resultData) {
+		this.name = _name;
+		this.reason = _reason;
+		this.resultData = _resultData;
+	};
+}

+ 70 - 0
src/main/java/com/persagy/cameractl/utils/ResultTools.java

@@ -0,0 +1,70 @@
+package com.persagy.cameractl.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+public class ResultTools {
+	public static final String err_param_not_found = "缺少必填参数";
+	public static final String err_param_time_limit = "时间超过限制";
+	public static final String err_param_format = "参数格式错误";
+	public static final String err_param_obj_id = "未找到指定id对象";
+	public static final String err_param_value_illegal = "参数值不合法:";
+	public static final String err_service = "服务错误:";
+	public static final String err_crud_save = "保存失败:";
+	public static final String err_crud_update = "更新失败:";
+	public static final String err_crud_delete = "删除失败:";
+	public static final String err_crud_query = "查询失败:";
+	public static final String result_success = "success";
+	public static final String result_failure = "failure";
+	public static final String key_result = "result";
+	public static final String key_err_message = "reason";
+	public static final String key_data = "data";
+	
+	public static String errorResult(String errorMsg) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_result, result_failure);
+		map.put(key_err_message, errorMsg);
+		return map2str(map);
+	}
+	
+	public static String illegalParamResult(String param) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_result, result_failure);
+		map.put(key_err_message, "param "+param+" is illegal");
+		return map2str(map);
+	}
+	
+	public static String successResult() {
+		return map2str(getDataResult());
+	}
+	
+	public static String successResult(String message) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_err_message, message);
+		return map2str(map);
+	}
+	
+	public static String dataResult(Object data) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_data, data);
+		return map2str(map);
+	}
+	
+	private static Map<String, Object> getDataResult() {
+		Map<String, Object> map = new HashMap<>();
+		map.put(key_result, result_success);
+		return map;
+	}
+	
+	private static String map2str(Map<String, Object> map) {
+		String result  = "{}";
+		try {
+			result = JsonTools.obj2Str(map);
+		} catch (JsonProcessingException e) {
+			e.printStackTrace();
+		}
+		return result;
+	}
+}

+ 310 - 0
src/main/java/com/persagy/cameractl/utils/StringTools.java

@@ -0,0 +1,310 @@
+package com.persagy.cameractl.utils;
+
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class StringTools {
+
+	/**
+	 * 获取UUID字符串
+	 * 
+	 * @param length 指定字符长度,范围(0,36],若为null则视length=36处理
+	 * @return 固定长度的数字+小写字母+中划线组合的UUID字符串
+	 */
+	public static String getUUID(Integer length) {
+		String uuidStr = UUID.randomUUID().toString();
+		if (null != length) {
+			length = length > 36 ? 36 : length;
+			uuidStr = uuidStr.substring(0, length);
+		}
+		return uuidStr;
+	}
+	
+	/**
+	 * 获取32位长度UUID
+	 * @return 32长度,只包含数字+小写字母
+	 */
+	public static String getUUID() {
+		return getUUID(36).replace("-", "");
+	}
+	
+	public static void main(String[] args) {
+		System.out.println(getUUID());
+	}
+	
+	/**
+	 * 获取字符串str对应的hash散列结果值
+	 * @param str
+	 * @return 000-999之间的数字字符串
+	 */
+	public static String getHashNum(String str) {
+		str = str == null ? "" : str;
+		
+		// 得到哈希正整数
+		int hashInt = Math.abs(str.hashCode());
+		
+		// 设置哈希字符值,长度为4位
+		hashInt = 100000 + hashInt % 1000;
+		String hashStr = ("" + hashInt).substring(3);
+		
+		return hashStr;
+	}
+
+	/**
+	 * 提供空字符串.
+	 */
+	public static final java.lang.String EMPTY = "";
+
+	/**
+	 * 判断字符串是否为null,或者是空串"", 或者是空格串" "
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean isBlank(String str) {
+		if (isEmpty(str)) {
+			return true;
+		}
+
+		return str.trim().length() == 0;
+	}
+
+	/**
+	 * 如果源字符串str为null,空串或空格串则返回默认字符串
+	 * 
+	 * @param str    源字符串
+	 * @param defStr 默认字符串
+	 * @return String
+	 */
+	public static String getDefault(String str, String defStr) {
+		return isBlank(str) ? defStr : str;
+	}
+
+	/**
+	 * 判断字符串是否为null,或者是空串"" .
+	 * 
+	 * @param s
+	 * @return boolean
+	 */
+	public static boolean isEmpty(String s) {
+		return (s == null || s.length() == 0);
+	}
+
+	/**
+	 * 判断字符串是否不为null,且不是空串"" .
+	 * 
+	 * @param s
+	 * @return boolean
+	 */
+	public static boolean isNotEmpty(String s) {
+		return !isEmpty(s);
+	}
+
+	public static final String toString(Object o) {
+		return o != null ? o.toString() : null;
+	}
+
+	/**
+	 * 判断是否为空格字符串 .
+	 * 
+	 * @param cs
+	 * @return boolean
+	 */
+	public static boolean isBlank(CharSequence cs) {
+		if (null == cs)
+			return false;
+		int length = cs.length();
+		for (int i = 0; i < length; i++) {
+			if (!Character.isWhitespace(cs.charAt(i)))
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * 比较字符串是否相等,都为null时,返回true .
+	 * 
+	 * @param string1
+	 * @param string2
+	 * @return boolean
+	 */
+	public static boolean equalsWithNull(String string1, String string2) {
+		if (string1 == null) {
+			if (string2 == null) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return string1.equals(string2);
+		}
+	}
+
+	public static boolean checkIsPhone(String phonenumber) {
+		String phone = "(^(d{3,4}-)?d{7,8})$|(1[0-9]{10})";
+		String tregEx = "[0-9]{7,8}"; // 表示a或f 0832-80691990
+		Pattern p = Pattern.compile(phone);
+		Matcher m = p.matcher(phonenumber);
+		Pattern p2 = Pattern.compile(tregEx);
+		Matcher m2 = p2.matcher(phonenumber);
+		// String regEx="[1]{1}[3,5,8,6]{1}[0-9]{9}"; //手机
+		// String tregEx="[0]{1}[0-9]{2,3}-[0-9]{7,8}"; //表示a或f 0832-80691990
+		return m.matches() || m2.matches();
+	}
+
+	/**
+	 * 判断字符串中是否包含汉字,如字符串为空,返回false .
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean hasHanZi(String str) {
+		if (StringTools.isEmpty(str)) {
+			return false;
+		}
+		String regEx = "[\\u4e00-\\u9fa5]";
+
+		Pattern pat = Pattern.compile(regEx);
+		Matcher mat = pat.matcher(str);
+		return mat.find();
+
+	}
+	
+	
+	/**
+     * 去除非汉字内容
+     */
+	public static String clearNotChinese(String buff){
+        String tmpString =buff.replaceAll("(?i)[^a-zA-Z0-9\u4E00-\u9FA5]", "");//去掉所有中英文符号
+        char[] carr = tmpString.toCharArray();
+        for(int i = 0; i<tmpString.length();i++){
+            if(carr[i] < 0xFF){
+                carr[i] = ' ' ;//过滤掉非汉字内容
+            }
+        }
+        return String.copyValueOf(carr).trim();
+    }
+
+	/**
+	 * 字符串中的数字转为*
+	 * 
+	 * @param str
+	 * @return String
+	 */
+	public static String spriceNumberic(String str) {
+		StringBuffer sb = new StringBuffer();
+		if (str != null) {
+			for (int i = 0; i < str.length(); i++) {
+				if (Character.isDigit(str.charAt(i))) {
+					sb.append("*");
+				} else {
+					sb.append(str.charAt(i));
+				}
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 去除字符里包含的回车(\n)、水平制表符(\t)、空格(\s)、换行(\r) .
+	 * 
+	 * @param str
+	 * @return String
+	 */
+	public static String replaceSpecilSign(String str) {
+		String dest = "";
+		if (isNotEmpty(str)) {
+			Pattern p = Pattern.compile("\\s*|\t|\r|\n");
+
+			Matcher m = p.matcher(str);
+
+			dest = m.replaceAll("");
+		}
+		return dest;
+	}
+
+	/**
+	 * 判断一个字符串是否为数字型字符串 .
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean isNumberic(String str) {
+		if (isEmpty(str)) {
+			return false;
+		}
+		Pattern pattern = Pattern.compile("[0-9]*");
+		return pattern.matcher(str).matches();
+	}
+
+	/**
+	 * 目标字符是否包含正则表达式所给字符 .
+	 * 
+	 * @param destStr 目标字符
+	 * @param regEx   正则表达式
+	 * @return boolean
+	 */
+	public static boolean containString(String destStr, String regEx) {
+		if (isEmpty(destStr)) {
+			return false;
+		}
+		if (isEmpty(regEx)) {
+			return false;
+		}
+		Pattern p = Pattern.compile(regEx);
+		Matcher m = p.matcher(destStr);
+		return m.find();
+	}
+
+	/**
+	 * Description: 判断字符串是否为合法的文件名(不包含后缀).
+	 * 
+	 * @param fileName
+	 * @return boolean
+	 */
+	public static boolean isFileName(String fileName) {
+		if (fileName == null || fileName.length() > 255) {
+			return false;
+		} else if (isBlank(fileName)) {
+			return true;
+		} else {
+			return fileName.matches(
+					"[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$");
+		}
+	}
+
+	/**
+	 * 将字符串首字母大写 .
+	 * 
+	 * @param s
+	 * @return String
+	 */
+	public static String capitalize(CharSequence s) {
+		if (null == s)
+			return null;
+		int len = s.length();
+		if (len == 0)
+			return "";
+		char char0 = s.charAt(0);
+		if (Character.isUpperCase(char0))
+			return s.toString();
+		return new StringBuilder(len).append(Character.toUpperCase(char0)).append(s.subSequence(1, len)).toString();
+	}
+
+	/**
+	 * 判断String是否为null或空
+	 * 
+	 * @param params
+	 * @return
+	 */
+	public static boolean isNull(String... params) {
+		for (String param : params) {
+			if (param == null || "".equals(param)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+}

+ 38 - 0
src/main/java/com/persagy/cameractl/utils/TimerInterval.java

@@ -0,0 +1,38 @@
+package com.persagy.cameractl.utils;
+
+import java.io.File;
+import java.util.Timer;
+
+/*
+ * 定时程序,目前包括:定时清除生成的mp4文件
+ * */
+public class TimerInterval {
+	public static void startClearFileTimer() {
+		Timer fileClearTimer = new Timer();
+//		0秒后开始响应函数,每隔五分钟执行一次
+		fileClearTimer.schedule(new ClearTileTimer(), 0, 1000 * 60 * 20);
+	};
+}
+
+class ClearTileTimer extends java.util.TimerTask {
+	@Override
+	public void run() {
+		String dirString = OtherTools.getVideoFileDir();
+		File dir = new File(dirString);
+		if (!dir.exists() || !dir.isDirectory()) {// 判断是否存在目录
+			return;
+		}
+		// 五分钟
+		long timeP = 1000 * 60 * 5;
+		long currTime = System.currentTimeMillis();
+		String[] files = dir.list();// 读取目录下的所有目录文件信息
+		for (int i = 0; i < files.length; i++) {// 循环,添加文件名或回调自身
+			File file = new File(dir, files[i]);
+			long lastModTime = file.lastModified();
+			// 5分钟以上的文件清除
+			if (currTime - lastModTime > timeP) {
+				file.delete();
+			}
+		}
+	}
+}

Plik diff jest za duży
+ 1 - 0
src/main/resources/application.yml