first commit
This commit is contained in:
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
67
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
67
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,67 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="ExtractMethodRecommender" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="minLength" value="745" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="HttpUrlsUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredUrls">
|
||||
<list>
|
||||
<option value="http://" />
|
||||
<option value="http://0.0.0.0" />
|
||||
<option value="http://127.0.0.1" />
|
||||
<option value="http://activemq.apache.org/schema/" />
|
||||
<option value="http://cxf.apache.org/schemas/" />
|
||||
<option value="http://java.sun.com/" />
|
||||
<option value="http://javafx.com/fxml" />
|
||||
<option value="http://javafx.com/javafx/" />
|
||||
<option value="http://json-schema.org/draft" />
|
||||
<option value="http://localhost" />
|
||||
<option value="http://maven.apache.org/POM/" />
|
||||
<option value="http://maven.apache.org/xsd/" />
|
||||
<option value="http://primefaces.org/ui" />
|
||||
<option value="http://schema.cloudfoundry.org/spring/" />
|
||||
<option value="http://schemas.xmlsoap.org/" />
|
||||
<option value="http://tiles.apache.org/" />
|
||||
<option value="http://www.ibm.com/webservices/xsd" />
|
||||
<option value="http://www.jboss.com/xml/ns/" />
|
||||
<option value="http://www.jboss.org/j2ee/schema/" />
|
||||
<option value="http://www.springframework.org/schema/" />
|
||||
<option value="http://www.springframework.org/security/tags" />
|
||||
<option value="http://www.springframework.org/tags" />
|
||||
<option value="http://www.thymeleaf.org" />
|
||||
<option value="http://www.w3.org/" />
|
||||
<option value="http://xmlns.jcp.org/" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="MethodNameSameAsClassName" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="RedundantCast" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="VulnerableLibrariesLocal" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="isIgnoringEnabled" value="true" />
|
||||
<option name="ignoredModules">
|
||||
<list>
|
||||
<option value="BirdStrikeSoetta" />
|
||||
<option value="BirdStrikeSoetta" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="ignoredPackages">
|
||||
<list>
|
||||
<option value="org.eclipse.jetty:jetty-http:11.0.23" />
|
||||
<option value="org.eclipse.jetty:jetty-server:11.0.23" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="ignoredReasons">
|
||||
<list>
|
||||
<option value="Not exploitable" />
|
||||
<option value="Not exploitable" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/jsLibraryMappings.xml
generated
Normal file
6
.idea/jsLibraryMappings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<file url="file://$PROJECT_DIR$" libraries="{jquery.dataTables}" />
|
||||
</component>
|
||||
</project>
|
||||
62
.idea/misc.xml
generated
Normal file
62
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="PWA">
|
||||
<option name="enabled" value="true" />
|
||||
<option name="wasEnabledAtLeastOnce" value="true" />
|
||||
</component>
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State />
|
||||
<State>
|
||||
<id>Android</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>CodePlugin DevKit</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>ComplianceLintAndroid</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>CorrectnessLintAndroid</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>LintAndroid</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>PerformanceLintAndroid</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Plugin DevKit</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>UsabilityLintAndroid</id>
|
||||
</State>
|
||||
</expanded-state>
|
||||
<selected-state>
|
||||
<State>
|
||||
<id>Android</id>
|
||||
</State>
|
||||
</selected-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="liberica-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
124
.idea/uiDesigner.xml
generated
Normal file
124
.idea/uiDesigner.xml
generated
Normal file
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
BIN
AudioFiles/elangWav.wav
Normal file
BIN
AudioFiles/elangWav.wav
Normal file
Binary file not shown.
BIN
AudioFiles/gunshotsWav.wav
Normal file
BIN
AudioFiles/gunshotsWav.wav
Normal file
Binary file not shown.
BIN
AudioFiles/pinkNoiseWav.wav
Normal file
BIN
AudioFiles/pinkNoiseWav.wav
Normal file
Binary file not shown.
19
Config/config.properties
Normal file
19
Config/config.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
# suppress inspection "UnusedProperty" for whole file
|
||||
Camera_ip = 192.168.10.17
|
||||
Camera_port = 80
|
||||
Camera_user = root
|
||||
Camera_password = password
|
||||
Camera_Rtsp_path = /axis-media/media.amp
|
||||
AudioFile01 = elangWav.wav
|
||||
AudioFile02 = gunshotsWav.wav
|
||||
AudioFile03 = pinkNoiseWav.wav
|
||||
AudioFile04 = 04.mp3
|
||||
AudioFile05 = 05.mp3
|
||||
AudioVolumeOutput = 100
|
||||
SerialPort = /dev/ttyUSB0
|
||||
SerialBaudRate = 9600
|
||||
PanTiltID = 1
|
||||
WebUsername = admin
|
||||
WebPassword = bandara
|
||||
WebHost = 0.0.0.0
|
||||
WebPort = 8080
|
||||
34
Config/simplelogger.properties
Normal file
34
Config/simplelogger.properties
Normal file
@@ -0,0 +1,34 @@
|
||||
# SLF4J's SimpleLogger configuration file
|
||||
# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
|
||||
|
||||
# Default logging detail level for all instances of SimpleLogger.
|
||||
# Must be one of ("trace", "debug", "info", "warn", or "error").
|
||||
# If not specified, defaults to "info".
|
||||
org.slf4j.simpleLogger.defaultLogLevel=warn
|
||||
|
||||
# Logging detail level for a SimpleLogger instance named "xxxxx".
|
||||
# Must be one of ("trace", "debug", "info", "warn", or "error").
|
||||
# If not specified, the default logging detail level is used.
|
||||
#org.slf4j.simpleLogger.log.xxxxx=
|
||||
|
||||
# Set to true if you want the current date and time to be included in output messages.
|
||||
# Default is false, and will output the number of milliseconds elapsed since startup.
|
||||
#org.slf4j.simpleLogger.showDateTime=false
|
||||
|
||||
# The date and time format to be used in the output messages.
|
||||
# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
|
||||
# If the format is not specified or is invalid, the default format is used.
|
||||
# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
|
||||
#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
|
||||
|
||||
# Set to true if you want to output the current thread name.
|
||||
# Defaults to true.
|
||||
#org.slf4j.simpleLogger.showThreadName=true
|
||||
|
||||
# Set to true if you want the Logger instance name to be included in output messages.
|
||||
# Defaults to true.
|
||||
#org.slf4j.simpleLogger.showLogName=true
|
||||
|
||||
# Set to true if you want the last component of the name to be included in output messages.
|
||||
# Defaults to false.
|
||||
#org.slf4j.simpleLogger.showShortLogName=false
|
||||
9
Config/tinylog.properties
Normal file
9
Config/tinylog.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
//writer = rolling file
|
||||
writer = console
|
||||
writer.file = logs/{date:yyyy-MM-dd}.log
|
||||
writer.format = {date:yyyy-MM-dd HH:mm:ss} {level}: {class}.{method}() {message}
|
||||
writer.policies = daily
|
||||
writer.buffered = true
|
||||
writer.charset = UTF-8
|
||||
writer.level = info
|
||||
writer.append = true
|
||||
5
Html/html/.idea/.gitignore
generated
vendored
Normal file
5
Html/html/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
8
Html/html/.idea/modules.xml
generated
Normal file
8
Html/html/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/LOGIN TENGAH.iml" filepath="$PROJECT_DIR$/.idea/LOGIN TENGAH.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
256
Html/html/index.html
Normal file
256
Html/html/index.html
Normal file
@@ -0,0 +1,256 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Bird Deterrent System</title>
|
||||
<link rel="stylesheet" type="text/css" href="public/style/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="public/style/bootstrap.min.css">
|
||||
<script src="public/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="public/style/jquery.dataTables.min.css">
|
||||
<script src="public/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="public/js/jquery.dataTables.min.js"></script>
|
||||
<script src="public/js/all.min.js"></script>
|
||||
<link rel="stylesheet" href="public/style/all.min.css">
|
||||
<script src="index.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark text-light container4">
|
||||
<div class="container-fluid">
|
||||
<!-- <p class="p-title">Bird Deterrent System</p>-->
|
||||
<a class="navbar-brand p-title" href="index.html">Bird Deterrent System</a>
|
||||
|
||||
<!-- Toggler/collapsible Button -->
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<!-- Collapsible Navbar -->
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item pad-menu">
|
||||
<a class="nav-link" href="setting.html">Setting</a>
|
||||
</li>
|
||||
<li class="nav-item pad-menu">
|
||||
<form action="/logout" method="get">
|
||||
<button class="btn btn-outline-light" type="submit">Logout</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!--<div class="container-fluid container4">-->
|
||||
<!-- <div class="row">-->
|
||||
<!-- <div class="col-12 col-sm-12 col-md-12 col-lg-8 col-xl-8 border-1">-->
|
||||
<!-- <h1 class="hr-lines">Bird Deterrent System</h1>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-4">-->
|
||||
<!-- <div class="container">-->
|
||||
<!-- <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12 outside-logout">-->
|
||||
<!-- <form action="/logout" method="get">-->
|
||||
<!-- <button class="btn btn-outline-light" type="submit">Logout</button>-->
|
||||
<!-- </form>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!--</div>-->
|
||||
<!-- SECTION 1-->
|
||||
|
||||
<!-- SECTION 2 -->
|
||||
<div class="container-fluid container3">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-8">
|
||||
<div class="outside">
|
||||
<img id="camerastream" src="public/images/not-available.png" class="img-cctv class100" alt="">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 col-sm-6 col-md-8 col-lg-8 col-xl-8">
|
||||
<p id="streaming_status">No Status</p>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-4 col-lg-4 col-xl-4">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="quality_video" onchange="change_video_quality()">
|
||||
<label class="form-check-label" for="quality_video">High Quality Video</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-4 ">
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-3 ">
|
||||
<p>Pan Speed</p>
|
||||
<div class="btn-group-vertical">
|
||||
<button id="pan1" class="btn btn-outline-dark btn-sm" value="16" onclick="set_pan_speed(16)">1</button>
|
||||
<button id="pan2" class="btn btn-outline-dark btn-sm" value="32" onclick="set_pan_speed(32)">2</button>
|
||||
<button id="pan3" class="btn btn-outline-dark btn-sm" value="48" onclick="set_pan_speed(48)">3</button>
|
||||
<button id="pan4" class="btn btn-outline-dark btn-sm" value="63" onclick="set_pan_speed(63)">4</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 outside">
|
||||
<div class="btn-circle">
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
<div class="col">
|
||||
<a onmousedown="btn_up()" onmouseup="stop_movement()">
|
||||
<i class="btn-nav fa-solid fa-caret-up pad-top" title="Up"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a onmousedown="btn_left()" onmouseup="stop_movement()">
|
||||
<i class="btn-nav fa-solid fa-caret-left pad-left" title="Left"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a>
|
||||
<i id="btn_center" class="btn-nav-center fa-solid fa-circle"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a onmousedown="btn_right()" onmouseup="stop_movement()">
|
||||
<i class="btn-nav fa-solid fa-caret-right pad-right" title="Right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
<div class="col">
|
||||
<a onmousedown="btn_down()" onmouseup="stop_movement()">
|
||||
<i class="i btn-nav fa-solid fa-caret-down pad-bottom" title="Down"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<p>Tilt Speed</p>
|
||||
<div class="btn-group-vertical">
|
||||
<button id="tilt1" class="btn btn-outline-dark btn-sm" value="16" onclick="set_tilt_speed(16)">1</button>
|
||||
<button id="tilt2" class="btn btn-outline-dark btn-sm" value="32" onclick="set_tilt_speed(32)">2</button>
|
||||
<button id="tilt3" class="btn btn-outline-dark btn-sm" value="48" onclick="set_tilt_speed(48)">3</button>
|
||||
<button id="tilt4" class="btn btn-outline-dark btn-sm" value="63" onclick="set_tilt_speed(63)">4</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-center">Zoom</p>
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<input id="zoom" type="range" class="form-range" min="1" max="10909" oninput="this.nextElementSibling.value = this.value">
|
||||
<output class="output"></output>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<button class="btn btn-primary" onclick="set_zoom()">SET</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <br>-->
|
||||
<div class="text-center">
|
||||
<h1 id="status_player" class="text-status1">Stop</h1>
|
||||
</div>
|
||||
<!-- <br>-->
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div id="div1" class="button-container">
|
||||
<a id="btn_play1" class="btn-play1 show" onclick='play_button(1)' title='Play Content 1'>
|
||||
<i class="fa-solid fa-play icon1"></i>
|
||||
</a>
|
||||
<a id="btn_stop1" class="btn-play1 hide" onclick='stop_button(1)' title='Stop Content 1'>
|
||||
<i class="fa-solid fa-stop icon1"></i>
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
<p> Content 1</p>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div id="div2" class="button-container">
|
||||
<a id="btn_play2" class="btn-play1 show" onclick='play_button(2)' title='Play Content 2'>
|
||||
<i class="fa-solid fa-play icon1"></i>
|
||||
</a>
|
||||
<a id="btn_stop2" class="btn-play1 hide" onclick='stop_button(2)' title='Stop Content 2'>
|
||||
<i class="fa-solid fa-stop icon1"></i>
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
<p> Content 2</p>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div id="div3" class="button-container">
|
||||
<a id="btn_play3" class="btn-play1 show" onclick='play_button(3)' title='Play Content 3'>
|
||||
<i class="fa-solid fa-play icon1"></i>
|
||||
</a>
|
||||
<a id="btn_stop3" class="btn-play1 hide" onclick='stop_button(3)' title='Stop Content 3'>
|
||||
<i class="fa-solid fa-stop icon1"></i>
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
<p> Content 3</p>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div id="div4" class="button-container">
|
||||
<a id="btn_play4" class="btn-play1 show" onclick='play_button(4)' title='Play Content 4'>
|
||||
<i class="fa-solid fa-play icon1"></i>
|
||||
</a>
|
||||
<a id="btn_stop4" class="btn-play1 hide" onclick='stop_button(4)' title='Stop Content 4'>
|
||||
<i class="fa-solid fa-stop icon1"></i>
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
<p> Content 4</p>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div id="div5" class="button-container">
|
||||
<a id="btn_play5" class="btn-play1 show" onclick='play_button(5)' title='Play Content 5'>
|
||||
<i class="fa-solid fa-play icon1"></i>
|
||||
</a>
|
||||
<a id="btn_stop5" class="btn-play1 hide" onclick='stop_button(5)' title='Stop Content 5'>
|
||||
<i class="fa-solid fa-stop icon1"></i>
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
<p>Content 5</p>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="customRange" class="form-label">Volume</label>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-10 pad-bar">
|
||||
<input id="customRange" type="range" class="form-range" min="0" max="100" step="10" oninput="set_volumeoutput(this.value)">
|
||||
<output id="volumebarvalue" class="output"></output>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div>
|
||||
<button id="mute" class="btn-mute show" onclick="mute()" title="mute">
|
||||
<i class="fa-solid fa-volume-high"></i>
|
||||
</button>
|
||||
<button id="unmute" class="btn-mute hide" onclick="unmute()" title="unmute">
|
||||
<i class="fa-solid fa-volume-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SECTION 3 -->
|
||||
<div class="container-fluid footer1 outside">
|
||||
<p>2024 Copyright © Galva Technologies. All rights reserved.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
400
Html/html/index.js
Normal file
400
Html/html/index.js
Normal file
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
* Speed of pan and tilt
|
||||
* @type {number} 0 - 3F (hex) / 63 (dec)
|
||||
*/
|
||||
let pan_speed = 20;
|
||||
let tilt_speed = 20;
|
||||
|
||||
/**
|
||||
* @type {WebSocket}
|
||||
*/
|
||||
let ws;
|
||||
|
||||
let camerastream;
|
||||
|
||||
let no_stream_counter = 0;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
camerastream = document.getElementById("camerastream");
|
||||
|
||||
setInterval(function (){
|
||||
no_stream_counter++;
|
||||
if (no_stream_counter>=20){
|
||||
if (camerastream){
|
||||
if (camerastream.src !== "public/images/not-available.png"){
|
||||
camerastream.src = "public/images/not-available.png";
|
||||
}
|
||||
}
|
||||
}
|
||||
},100);
|
||||
|
||||
ws = new WebSocket("/ws");
|
||||
|
||||
ws.onopen = function(){
|
||||
console.log("Connected to the server");
|
||||
|
||||
// request basic parameters
|
||||
ws.send(JSON.stringify({
|
||||
command: "GET MAX ZOOM",
|
||||
data: 0
|
||||
}));
|
||||
ws.send(JSON.stringify({
|
||||
command: "GET VOLUME",
|
||||
data: 0
|
||||
}));
|
||||
ws.send(JSON.stringify({
|
||||
command: "GET ZOOM",
|
||||
data: 0
|
||||
}));
|
||||
ws.send(JSON.stringify({
|
||||
command: "GET RESOLUTION",
|
||||
data: 0
|
||||
}));
|
||||
ws.send(JSON.stringify({
|
||||
command: "STREAMING STATUS",
|
||||
data: 0
|
||||
}));
|
||||
}
|
||||
ws.onmessage = function(event){
|
||||
//console.log("Received data from server: " + event.data);
|
||||
/**
|
||||
* @type {{reply: string, data: string|number}} dx
|
||||
*/
|
||||
let dx = JSON.parse(event.data);
|
||||
switch (dx.reply){
|
||||
case "GET BASE64":
|
||||
if (dx.data.startsWith("data:image/jpeg;base64,")){
|
||||
update_camerastream(dx.data);
|
||||
no_stream_counter = 0;
|
||||
} else update_camerastream(null);
|
||||
break;
|
||||
case "SET VOLUME":
|
||||
console.log("Set Volume: "+dx.data);
|
||||
break;
|
||||
case "GET VOLUME":
|
||||
console.log("Get Volume: "+dx.data);
|
||||
$('#customRange').val(dx.data);
|
||||
break;
|
||||
case "GET MAX ZOOM":
|
||||
console.log("Get Max Zoom: "+dx.data);
|
||||
$('#zoom')
|
||||
.attr("max", dx.data)
|
||||
.attr("min", 1);
|
||||
|
||||
|
||||
break;
|
||||
case "GET ZOOM":
|
||||
console.log("Get Zoom: "+dx.data);
|
||||
$('#zoom').val(dx.data);
|
||||
break;
|
||||
case "GET RESOLUTION":
|
||||
console.log("Get Resolution: "+dx.data);
|
||||
break;
|
||||
case "PAN LEFT":
|
||||
console.log("Pan Left");
|
||||
break;
|
||||
case "PAN RIGHT":
|
||||
console.log("Pan Right");
|
||||
break;
|
||||
case "TILT UP":
|
||||
console.log("Tilt Up");
|
||||
break;
|
||||
case "TILT DOWN":
|
||||
console.log("Tilt Down");
|
||||
break;
|
||||
case "STOP MOVEMENT":
|
||||
console.log("Stop Movement");
|
||||
break;
|
||||
case "SET ZOOM":
|
||||
console.log("Set Zoom: "+dx.data);
|
||||
break;
|
||||
case "PLAY AUDIO":
|
||||
console.log("Play Audio: "+dx.data);
|
||||
if (dx.data.startsWith("Failed")){
|
||||
alert(dx.data);
|
||||
} else $('#status_player').html("Playing Audio "+dx.data);
|
||||
break;
|
||||
case "STOP AUDIO":
|
||||
console.log("Stop Audio");
|
||||
$('#status_player').html("Stop Playback");
|
||||
break;
|
||||
case 'SET VIDEO QUALITY':
|
||||
console.log("Set Video Quality: "+dx.data);
|
||||
break;
|
||||
case "STREAMING STATUS":
|
||||
console.log("Streaming Status: "+dx.data);
|
||||
$('#streaming_status').html(dx.data);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
ws.onclose = function(){
|
||||
console.log("Connection closed");
|
||||
}
|
||||
ws.onerror = function(){
|
||||
console.log("Error in connection");
|
||||
}
|
||||
|
||||
set_pan_speed(32);
|
||||
set_tilt_speed(32);
|
||||
});
|
||||
|
||||
/**
|
||||
* Update camera stream
|
||||
* @param {String} value
|
||||
*/
|
||||
function update_camerastream(value){
|
||||
if (value && value.length>0){
|
||||
if (camerastream) camerastream.src = value;
|
||||
} else {
|
||||
if (camerastream) camerastream.src = "public/images/not-available.png";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function play_off(index){
|
||||
$('#div'+index).prop("className", "button-container div-disabled");
|
||||
$('#btn_play'+index).prop("className", "btn-play1 show text-light");
|
||||
|
||||
}
|
||||
|
||||
function play_on(index){
|
||||
$('#div'+index).prop("className", "button-container");
|
||||
$('#btn_play'+index).prop("className", "btn-play1 show");
|
||||
}
|
||||
|
||||
function show_play_and_hide_stop(index){
|
||||
$('#btn_play'+index).prop("className", "btn-play1 show"); ;
|
||||
$('#btn_stop'+index).prop("className", "btn-play1 hide");
|
||||
}
|
||||
|
||||
function show_stop_and_hide_play(index){
|
||||
$('#btn_play'+index).prop("className", "btn-play1 hide");
|
||||
$('#btn_stop'+index).prop("className", "btn-play1 show");
|
||||
|
||||
}
|
||||
|
||||
function allplay(){
|
||||
for (let i = 0; i < 5; i++) play_on(i+1);
|
||||
}
|
||||
|
||||
function play_button(index){
|
||||
show_stop_and_hide_play(index);
|
||||
$('#status_player').html("Play");
|
||||
for (let i = 1; i <= 5; i++){
|
||||
if (i!==index) play_off(i);
|
||||
}
|
||||
send_play_audio(index);
|
||||
}
|
||||
|
||||
function stop_button(index){
|
||||
show_play_and_hide_stop(index);
|
||||
$('#status_player').html("Stop");
|
||||
|
||||
allplay();
|
||||
send_stop_audio();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send command to stop audio
|
||||
*/
|
||||
function send_stop_audio(){
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "STOP AUDIO",
|
||||
data: 0
|
||||
}));
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command to play audio
|
||||
* @param {number} index 1 - 5
|
||||
*/
|
||||
function send_play_audio(index){
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "PLAY AUDIO",
|
||||
data: index
|
||||
}));
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
|
||||
function unmute(){
|
||||
$('#mute').prop("className", "btn-mute show");
|
||||
$('#unmute').prop("className", "btn-mute hide");
|
||||
console.log("unmute")
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "UNMUTE",
|
||||
data: 0
|
||||
}));
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
function mute(){
|
||||
$('#mute').prop("className", "btn-mute hide");
|
||||
$('#unmute').prop("className", "btn-mute show");
|
||||
|
||||
console.log("mute")
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "MUTE",
|
||||
data: 0
|
||||
}));
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
|
||||
function btn_center_off(){
|
||||
$('#btn_center').prop("className", "btn-center-unactive fa-solid fa-circle");
|
||||
}
|
||||
|
||||
function btn_up(){
|
||||
console.log("btn_up")
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "TILT UP",
|
||||
data: tilt_speed
|
||||
}));
|
||||
btn_center_off()
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
function btn_left(){
|
||||
console.log("btn_left")
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "PAN LEFT",
|
||||
data: pan_speed
|
||||
}));
|
||||
btn_center_off();
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
function btn_right(){
|
||||
console.log("btn_right")
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "PAN RIGHT",
|
||||
data: pan_speed
|
||||
}));
|
||||
btn_center_off()
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
function btn_down(){
|
||||
console.log("btn_down")
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "TILT DOWN",
|
||||
data: tilt_speed
|
||||
}));
|
||||
btn_center_off()
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
|
||||
function stop_movement(){
|
||||
console.log("stop_movement")
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "STOP MOVEMENT",
|
||||
data: 0
|
||||
}));
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
|
||||
function set_zoom(){
|
||||
let zoom = document.getElementById("zoom");
|
||||
console.log("set_zoom "+zoom.value)
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "SET ZOOM",
|
||||
data: zoom.value
|
||||
}));
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
|
||||
function set_volumeoutput(value){
|
||||
$('#volumebarvalue').val(value);
|
||||
|
||||
console.log("set_volumeoutput "+value)
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "SET VOLUME",
|
||||
data: value
|
||||
}));
|
||||
} else console.log("WebSocket is not open");
|
||||
}
|
||||
|
||||
function set_pan_speed(value){
|
||||
pan_speed = value;
|
||||
console.log("set_pan_speed "+value);
|
||||
clearpan();
|
||||
let classvalue = "btn btn-dark btn-sm";
|
||||
switch(pan_speed){
|
||||
case 16:
|
||||
$('#pan1').prop("className", classvalue );
|
||||
break;
|
||||
case 32:
|
||||
$('#pan2').prop("className", classvalue);
|
||||
break;
|
||||
case 48:
|
||||
$('#pan3').prop("className", classvalue);
|
||||
break;
|
||||
case 63:
|
||||
$('#pan4').prop("className", classvalue);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function set_tilt_speed(value){
|
||||
tilt_speed = value;
|
||||
console.log("set_tilt_speed "+value);
|
||||
cleartilt();
|
||||
let classvalue = "btn btn-dark btn-sm";
|
||||
switch (tilt_speed){
|
||||
case 16:
|
||||
$('#tilt1').prop("className", classvalue);
|
||||
break;
|
||||
case 32:
|
||||
$('#tilt2').prop("className", classvalue);
|
||||
break;
|
||||
case 48:
|
||||
$('#tilt3').prop("className", classvalue);
|
||||
break;
|
||||
case 63:
|
||||
$('#tilt4').prop("className", classvalue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Pan Tilt Speed
|
||||
function clearpan(){
|
||||
for(let i = 1; i <= 4; i++){
|
||||
$('#pan'+i).prop("className", "btn btn-outline-dark btn-sm");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function cleartilt(){
|
||||
for(let i = 1; i <= 4; i++){
|
||||
$('#tilt'+i).prop("className", "btn btn-outline-dark btn-sm");
|
||||
}
|
||||
}
|
||||
|
||||
function change_video_quality(){
|
||||
let btn = document.getElementById("quality_video")
|
||||
console.log('High Quality Video: '+btn.checked?'ON':'OFF');
|
||||
if (ws.readyState === WebSocket.OPEN){
|
||||
ws.send(JSON.stringify({
|
||||
command: "SET VIDEO QUALITY",
|
||||
data: btn.checked?"HQ":"LQ"
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
41
Html/html/login.html
Normal file
41
Html/html/login.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Bird Deterrent System</title>
|
||||
<link rel="stylesheet" type="text/css" href="public/style/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="public/style/bootstrap.min.css">
|
||||
<script src="index.js"></script>
|
||||
<script src="public/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="public/style/jquery.dataTables.min.css">
|
||||
<script src="public/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="public/js/jquery.dataTables.min.js"></script>
|
||||
<!--Link for Icon Fontawesome-->
|
||||
<script src="public/js/all.min.js"></script>
|
||||
<link rel="stylesheet" href="public/style/all.min.css">
|
||||
<script src="login.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="bg-img">
|
||||
<div class="content">
|
||||
<header>Login</header>
|
||||
<form action="/login" method="post">
|
||||
<div class="field space input-rad">
|
||||
<span class="fa-solid fa-user"></span>
|
||||
<input id="username" placeholder="username" name="username" required>
|
||||
</div>
|
||||
<div class="field space input-rad">
|
||||
<span class="fa-solid fa-lock"></span>
|
||||
<input id='login_password' type='password' placeholder='Password' name='password' required>
|
||||
<span class="fa-solid fa-eye" id='buttonShowPasswordLogin' onclick="showPasswordLogin()"></span>
|
||||
</div>
|
||||
<div class="class100 space">
|
||||
<button class="btn btn-primary btn-lg w-100" type="submit">Log In</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
10
Html/html/login.js
Normal file
10
Html/html/login.js
Normal file
@@ -0,0 +1,10 @@
|
||||
function showPasswordLogin() {
|
||||
const show = document.getElementById('login_password').type;
|
||||
if (show === 'password') {
|
||||
document.getElementById('login_password').type = 'text';
|
||||
document.getElementById('buttonShowPasswordLogin').className = 'fa-solid fa-eye-slash';
|
||||
} else {
|
||||
document.getElementById('login_password').type = 'password';
|
||||
document.getElementById('buttonShowPasswordLogin').className = 'fa-solid fa-eye';
|
||||
}
|
||||
}
|
||||
BIN
Html/html/public/images/airport-terminal.jpg
Normal file
BIN
Html/html/public/images/airport-terminal.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 MiB |
BIN
Html/html/public/images/not-available.png
Normal file
BIN
Html/html/public/images/not-available.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
6
Html/html/public/js/all.min.js
vendored
Normal file
6
Html/html/public/js/all.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
Html/html/public/js/bootstrap.bundle.min.js
vendored
Normal file
7
Html/html/public/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
Html/html/public/js/jquery-3.6.0.min.js
vendored
Normal file
2
Html/html/public/js/jquery-3.6.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
Html/html/public/js/jquery-3.7.1.min.js
vendored
Normal file
2
Html/html/public/js/jquery-3.7.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
Html/html/public/js/jquery.dataTables.min.js
vendored
Normal file
4
Html/html/public/js/jquery.dataTables.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
Html/html/public/style/all.min.css
vendored
Normal file
12
Html/html/public/style/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
515
Html/html/public/style/bootstrap.css
vendored
Normal file
515
Html/html/public/style/bootstrap.css
vendored
Normal file
@@ -0,0 +1,515 @@
|
||||
@charset "UTF-8";
|
||||
:root {
|
||||
--dt-row-selected: 13, 110, 253;
|
||||
--dt-row-selected-text: 255, 255, 255;
|
||||
--dt-row-selected-link: 9, 10, 11;
|
||||
--dt-row-stripe: 0, 0, 0;
|
||||
--dt-row-hover: 0, 0, 0;
|
||||
--dt-column-ordering: 0, 0, 0;
|
||||
--dt-html-background: white;
|
||||
}
|
||||
:root.dark {
|
||||
--dt-html-background: rgb(33, 37, 41);
|
||||
}
|
||||
|
||||
table.dataTable td.dt-control {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
table.dataTable td.dt-control:before {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
content: "";
|
||||
border-top: 5px solid transparent;
|
||||
border-left: 10px solid rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 5px solid transparent;
|
||||
border-right: 0px solid transparent;
|
||||
}
|
||||
table.dataTable tr.dt-hasChild td.dt-control:before {
|
||||
border-top: 10px solid rgba(0, 0, 0, 0.5);
|
||||
border-left: 5px solid transparent;
|
||||
border-bottom: 0px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
||||
html.dark table.dataTable td.dt-control:before,
|
||||
:root[data-bs-theme=dark] table.dataTable td.dt-control:before,
|
||||
:root[data-theme=dark] table.dataTable td.dt-control:before {
|
||||
border-left-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
html.dark table.dataTable tr.dt-hasChild td.dt-control:before,
|
||||
:root[data-bs-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before,
|
||||
:root[data-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before {
|
||||
border-top-color: rgba(255, 255, 255, 0.5);
|
||||
border-left-color: transparent;
|
||||
}
|
||||
|
||||
div.dt-scroll {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.dt-scroll-body thead tr,
|
||||
div.dt-scroll-body tfoot tr {
|
||||
height: 0;
|
||||
}
|
||||
div.dt-scroll-body thead tr th, div.dt-scroll-body thead tr td,
|
||||
div.dt-scroll-body tfoot tr th,
|
||||
div.dt-scroll-body tfoot tr td {
|
||||
height: 0 !important;
|
||||
padding-top: 0px !important;
|
||||
padding-bottom: 0px !important;
|
||||
border-top-width: 0px !important;
|
||||
border-bottom-width: 0px !important;
|
||||
}
|
||||
div.dt-scroll-body thead tr th div.dt-scroll-sizing, div.dt-scroll-body thead tr td div.dt-scroll-sizing,
|
||||
div.dt-scroll-body tfoot tr th div.dt-scroll-sizing,
|
||||
div.dt-scroll-body tfoot tr td div.dt-scroll-sizing {
|
||||
height: 0 !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
table.dataTable thead > tr > th:active,
|
||||
table.dataTable thead > tr > td:active {
|
||||
outline: none;
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before {
|
||||
position: absolute;
|
||||
display: block;
|
||||
bottom: 50%;
|
||||
content: "▲";
|
||||
content: "▲"/"";
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 50%;
|
||||
content: "▼";
|
||||
content: "▼"/"";
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, table.dataTable thead > tr > th.dt-ordering-asc, table.dataTable thead > tr > th.dt-ordering-desc,
|
||||
table.dataTable thead > tr > td.dt-orderable-asc,
|
||||
table.dataTable thead > tr > td.dt-orderable-desc,
|
||||
table.dataTable thead > tr > td.dt-ordering-asc,
|
||||
table.dataTable thead > tr > td.dt-ordering-desc {
|
||||
position: relative;
|
||||
padding-right: 30px;
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order,
|
||||
table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order,
|
||||
table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order,
|
||||
table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order,
|
||||
table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 12px;
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:after, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after {
|
||||
left: 0;
|
||||
opacity: 0.125;
|
||||
line-height: 9px;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc,
|
||||
table.dataTable thead > tr > td.dt-orderable-asc,
|
||||
table.dataTable thead > tr > td.dt-orderable-desc {
|
||||
cursor: pointer;
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-orderable-asc:hover, table.dataTable thead > tr > th.dt-orderable-desc:hover,
|
||||
table.dataTable thead > tr > td.dt-orderable-asc:hover,
|
||||
table.dataTable thead > tr > td.dt-orderable-desc:hover {
|
||||
outline: 2px solid rgba(0, 0, 0, 0.05);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after {
|
||||
opacity: 0.6;
|
||||
}
|
||||
table.dataTable thead > tr > th.sorting_desc_disabled span.dt-column-order:after, table.dataTable thead > tr > th.sorting_asc_disabled span.dt-column-order:before,
|
||||
table.dataTable thead > tr > td.sorting_desc_disabled span.dt-column-order:after,
|
||||
table.dataTable thead > tr > td.sorting_asc_disabled span.dt-column-order:before {
|
||||
display: none;
|
||||
}
|
||||
table.dataTable thead > tr > th:active,
|
||||
table.dataTable thead > tr > td:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
div.dt-scroll-body > table.dataTable > thead > tr > th,
|
||||
div.dt-scroll-body > table.dataTable > thead > tr > td {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:root.dark table.dataTable thead > tr > th.dt-orderable-asc:hover, :root.dark table.dataTable thead > tr > th.dt-orderable-desc:hover,
|
||||
:root.dark table.dataTable thead > tr > td.dt-orderable-asc:hover,
|
||||
:root.dark table.dataTable thead > tr > td.dt-orderable-desc:hover,
|
||||
:root[data-bs-theme=dark] table.dataTable thead > tr > th.dt-orderable-asc:hover,
|
||||
:root[data-bs-theme=dark] table.dataTable thead > tr > th.dt-orderable-desc:hover,
|
||||
:root[data-bs-theme=dark] table.dataTable thead > tr > td.dt-orderable-asc:hover,
|
||||
:root[data-bs-theme=dark] table.dataTable thead > tr > td.dt-orderable-desc:hover {
|
||||
outline: 2px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
div.dt-processing {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 200px;
|
||||
margin-left: -100px;
|
||||
margin-top: -22px;
|
||||
text-align: center;
|
||||
padding: 2px;
|
||||
z-index: 10;
|
||||
}
|
||||
div.dt-processing > div:last-child {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 15px;
|
||||
margin: 1em auto;
|
||||
}
|
||||
div.dt-processing > div:last-child > div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 50%;
|
||||
background: rgb(13, 110, 253);
|
||||
background: rgb(var(--dt-row-selected));
|
||||
animation-timing-function: cubic-bezier(0, 1, 1, 0);
|
||||
}
|
||||
div.dt-processing > div:last-child > div:nth-child(1) {
|
||||
left: 8px;
|
||||
animation: datatables-loader-1 0.6s infinite;
|
||||
}
|
||||
div.dt-processing > div:last-child > div:nth-child(2) {
|
||||
left: 8px;
|
||||
animation: datatables-loader-2 0.6s infinite;
|
||||
}
|
||||
div.dt-processing > div:last-child > div:nth-child(3) {
|
||||
left: 32px;
|
||||
animation: datatables-loader-2 0.6s infinite;
|
||||
}
|
||||
div.dt-processing > div:last-child > div:nth-child(4) {
|
||||
left: 56px;
|
||||
animation: datatables-loader-3 0.6s infinite;
|
||||
}
|
||||
|
||||
@keyframes datatables-loader-1 {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes datatables-loader-3 {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(0);
|
||||
}
|
||||
}
|
||||
@keyframes datatables-loader-2 {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
100% {
|
||||
transform: translate(24px, 0);
|
||||
}
|
||||
}
|
||||
table.dataTable.nowrap th, table.dataTable.nowrap td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
table.dataTable th,
|
||||
table.dataTable td {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
table.dataTable th.dt-left,
|
||||
table.dataTable td.dt-left {
|
||||
text-align: left;
|
||||
}
|
||||
table.dataTable th.dt-center,
|
||||
table.dataTable td.dt-center {
|
||||
text-align: center;
|
||||
}
|
||||
table.dataTable th.dt-right,
|
||||
table.dataTable td.dt-right {
|
||||
text-align: right;
|
||||
}
|
||||
table.dataTable th.dt-justify,
|
||||
table.dataTable td.dt-justify {
|
||||
text-align: justify;
|
||||
}
|
||||
table.dataTable th.dt-nowrap,
|
||||
table.dataTable td.dt-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
table.dataTable th.dt-empty,
|
||||
table.dataTable td.dt-empty {
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
}
|
||||
table.dataTable th.dt-type-numeric, table.dataTable th.dt-type-date,
|
||||
table.dataTable td.dt-type-numeric,
|
||||
table.dataTable td.dt-type-date {
|
||||
text-align: right;
|
||||
}
|
||||
table.dataTable thead th,
|
||||
table.dataTable thead td,
|
||||
table.dataTable tfoot th,
|
||||
table.dataTable tfoot td {
|
||||
text-align: left;
|
||||
}
|
||||
table.dataTable thead th.dt-head-left,
|
||||
table.dataTable thead td.dt-head-left,
|
||||
table.dataTable tfoot th.dt-head-left,
|
||||
table.dataTable tfoot td.dt-head-left {
|
||||
text-align: left;
|
||||
}
|
||||
table.dataTable thead th.dt-head-center,
|
||||
table.dataTable thead td.dt-head-center,
|
||||
table.dataTable tfoot th.dt-head-center,
|
||||
table.dataTable tfoot td.dt-head-center {
|
||||
text-align: center;
|
||||
}
|
||||
table.dataTable thead th.dt-head-right,
|
||||
table.dataTable thead td.dt-head-right,
|
||||
table.dataTable tfoot th.dt-head-right,
|
||||
table.dataTable tfoot td.dt-head-right {
|
||||
text-align: right;
|
||||
}
|
||||
table.dataTable thead th.dt-head-justify,
|
||||
table.dataTable thead td.dt-head-justify,
|
||||
table.dataTable tfoot th.dt-head-justify,
|
||||
table.dataTable tfoot td.dt-head-justify {
|
||||
text-align: justify;
|
||||
}
|
||||
table.dataTable thead th.dt-head-nowrap,
|
||||
table.dataTable thead td.dt-head-nowrap,
|
||||
table.dataTable tfoot th.dt-head-nowrap,
|
||||
table.dataTable tfoot td.dt-head-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
table.dataTable tbody th.dt-body-left,
|
||||
table.dataTable tbody td.dt-body-left {
|
||||
text-align: left;
|
||||
}
|
||||
table.dataTable tbody th.dt-body-center,
|
||||
table.dataTable tbody td.dt-body-center {
|
||||
text-align: center;
|
||||
}
|
||||
table.dataTable tbody th.dt-body-right,
|
||||
table.dataTable tbody td.dt-body-right {
|
||||
text-align: right;
|
||||
}
|
||||
table.dataTable tbody th.dt-body-justify,
|
||||
table.dataTable tbody td.dt-body-justify {
|
||||
text-align: justify;
|
||||
}
|
||||
table.dataTable tbody th.dt-body-nowrap,
|
||||
table.dataTable tbody td.dt-body-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/*! Bootstrap 5 integration for DataTables
|
||||
*
|
||||
* ©2020 SpryMedia Ltd, all rights reserved.
|
||||
* License: MIT datatables.net/license/mit
|
||||
*/
|
||||
table.table.dataTable {
|
||||
clear: both;
|
||||
margin-bottom: 0;
|
||||
max-width: none;
|
||||
border-spacing: 0;
|
||||
}
|
||||
table.table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1) > * {
|
||||
box-shadow: none;
|
||||
}
|
||||
table.table.dataTable > :not(caption) > * > * {
|
||||
background-color: var(--bs-table-bg);
|
||||
}
|
||||
table.table.dataTable > tbody > tr {
|
||||
background-color: transparent;
|
||||
}
|
||||
table.table.dataTable > tbody > tr.selected > * {
|
||||
box-shadow: inset 0 0 0 9999px rgb(13, 110, 253);
|
||||
box-shadow: inset 0 0 0 9999px rgb(var(--dt-row-selected));
|
||||
color: rgb(255, 255, 255);
|
||||
color: rgb(var(--dt-row-selected-text));
|
||||
}
|
||||
table.table.dataTable > tbody > tr.selected a {
|
||||
color: rgb(9, 10, 11);
|
||||
color: rgb(var(--dt-row-selected-link));
|
||||
}
|
||||
table.table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1) > * {
|
||||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-stripe), 0.05);
|
||||
}
|
||||
table.table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1).selected > * {
|
||||
box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.95);
|
||||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.95);
|
||||
}
|
||||
table.table.dataTable.table-hover > tbody > tr:hover > * {
|
||||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.075);
|
||||
}
|
||||
table.table.dataTable.table-hover > tbody > tr.selected:hover > * {
|
||||
box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.975);
|
||||
box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.975);
|
||||
}
|
||||
|
||||
div.dt-container div.dt-layout-start > *:not(:last-child) {
|
||||
margin-right: 1em;
|
||||
}
|
||||
div.dt-container div.dt-layout-end > *:not(:first-child) {
|
||||
margin-left: 1em;
|
||||
}
|
||||
div.dt-container div.dt-layout-full {
|
||||
width: 100%;
|
||||
}
|
||||
div.dt-container div.dt-layout-full > *:only-child {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
div.dt-container div.dt-layout-table > div {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
div.dt-container div.dt-layout-start > *:not(:last-child) {
|
||||
margin-right: 0;
|
||||
}
|
||||
div.dt-container div.dt-layout-end > *:not(:first-child) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
div.dt-container div.dt-length label {
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
div.dt-container div.dt-length select {
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
div.dt-container div.dt-search {
|
||||
text-align: right;
|
||||
}
|
||||
div.dt-container div.dt-search label {
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
div.dt-container div.dt-search input {
|
||||
margin-left: 0.5em;
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
}
|
||||
div.dt-container div.dt-paging {
|
||||
margin: 0;
|
||||
}
|
||||
div.dt-container div.dt-paging ul.pagination {
|
||||
margin: 2px 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
div.dt-container div.dt-row {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.dt-scroll-head table.dataTable {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
div.dt-scroll-body {
|
||||
border-bottom-color: var(--bs-border-color);
|
||||
border-bottom-width: var(--bs-border-width);
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
div.dt-scroll-body > table {
|
||||
border-top: none;
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
div.dt-scroll-body > table > tbody > tr:first-child {
|
||||
border-top-width: 0;
|
||||
}
|
||||
div.dt-scroll-body > table > thead > tr {
|
||||
border-width: 0 !important;
|
||||
}
|
||||
div.dt-scroll-body > table > tbody > tr:last-child > * {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
div.dt-scroll-foot > .dt-scroll-footInner {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
div.dt-scroll-foot > .dt-scroll-footInner > table {
|
||||
margin-top: 0 !important;
|
||||
border-top: none;
|
||||
}
|
||||
div.dt-scroll-foot > .dt-scroll-footInner > table > tfoot > tr:first-child {
|
||||
border-top-width: 0 !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
div.dt-container div.dt-length,
|
||||
div.dt-container div.dt-search,
|
||||
div.dt-container div.dt-info,
|
||||
div.dt-container div.dt-paging {
|
||||
text-align: center;
|
||||
}
|
||||
div.dt-container .row {
|
||||
--bs-gutter-y: 0.5rem;
|
||||
}
|
||||
div.dt-container div.dt-paging ul.pagination {
|
||||
justify-content: center !important;
|
||||
}
|
||||
}
|
||||
table.dataTable.table-sm > thead > tr th.dt-orderable-asc, table.dataTable.table-sm > thead > tr th.dt-orderable-desc, table.dataTable.table-sm > thead > tr th.dt-ordering-asc, table.dataTable.table-sm > thead > tr th.dt-ordering-desc,
|
||||
table.dataTable.table-sm > thead > tr td.dt-orderable-asc,
|
||||
table.dataTable.table-sm > thead > tr td.dt-orderable-desc,
|
||||
table.dataTable.table-sm > thead > tr td.dt-ordering-asc,
|
||||
table.dataTable.table-sm > thead > tr td.dt-ordering-desc {
|
||||
padding-right: 20px;
|
||||
}
|
||||
table.dataTable.table-sm > thead > tr th.dt-orderable-asc span.dt-column-order, table.dataTable.table-sm > thead > tr th.dt-orderable-desc span.dt-column-order, table.dataTable.table-sm > thead > tr th.dt-ordering-asc span.dt-column-order, table.dataTable.table-sm > thead > tr th.dt-ordering-desc span.dt-column-order,
|
||||
table.dataTable.table-sm > thead > tr td.dt-orderable-asc span.dt-column-order,
|
||||
table.dataTable.table-sm > thead > tr td.dt-orderable-desc span.dt-column-order,
|
||||
table.dataTable.table-sm > thead > tr td.dt-ordering-asc span.dt-column-order,
|
||||
table.dataTable.table-sm > thead > tr td.dt-ordering-desc span.dt-column-order {
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
div.dt-scroll-head table.table-bordered {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
div.table-responsive > div.dt-container > div.row {
|
||||
margin: 0;
|
||||
}
|
||||
div.table-responsive > div.dt-container > div.row > div[class^=col-]:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
div.table-responsive > div.dt-container > div.row > div[class^=col-]:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
:root[data-bs-theme=dark] {
|
||||
--dt-row-hover: 255, 255, 255;
|
||||
--dt-row-stripe: 255, 255, 255;
|
||||
--dt-column-ordering: 255, 255, 255;
|
||||
}
|
||||
7
Html/html/public/style/bootstrap.min.css
vendored
Normal file
7
Html/html/public/style/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
Html/html/public/style/jquery.dataTables.min.css
vendored
Normal file
1
Html/html/public/style/jquery.dataTables.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
822
Html/html/public/style/style.css
Normal file
822
Html/html/public/style/style.css
Normal file
@@ -0,0 +1,822 @@
|
||||
html,body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
background-color: black;
|
||||
}
|
||||
body{
|
||||
overflow: visible;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
/*HEADER */
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--header-outer-height: 110px;
|
||||
--header-inner-height: 70px;
|
||||
--header-height-difference: calc(
|
||||
var(--header-outer-height) - var(--header-inner-height)
|
||||
);
|
||||
--header-bg: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "DM Sans", sans-serif;
|
||||
background-color: #f2f5f7;
|
||||
line-height: 1.5;
|
||||
/*min-height: 300vh;*/
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.responsive-wrapper {
|
||||
width: 90%;
|
||||
max-width: 1280px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* Sticky header */
|
||||
.header-outer {
|
||||
/* Make it stick */
|
||||
height: var(--header-outer-height);
|
||||
position: sticky;
|
||||
top: calc(
|
||||
var(--header-height-difference) * -1
|
||||
); /* Multiply by -1 to get a negative value */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
/* Other */
|
||||
background-color: var(--header-bg);
|
||||
box-shadow: 0 2px 10px 0 rgba(0,0,0, 0.1);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
/* Make it stick */
|
||||
height: var(--header-inner-height);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
||||
/* Other */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Styling of other elements */
|
||||
.header-logo img {
|
||||
display: block;
|
||||
height: calc(var(--header-inner-height) - 30px);
|
||||
}
|
||||
|
||||
.header-navigation {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.header-navigation a,
|
||||
.header-navigation button {
|
||||
font-size: 1.125rem;
|
||||
color: inherit;
|
||||
margin-left: 1.75rem;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.header-navigation a {
|
||||
display: none;
|
||||
font-size: 1.125rem;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.header-navigation button {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.header-navigation a:hover:after,
|
||||
.header-navigation button:hover:after {
|
||||
transform: scalex(1);
|
||||
}
|
||||
|
||||
.header-navigation a:after,
|
||||
.header-navigation button:after {
|
||||
transition: 0.25s ease;
|
||||
content: "";
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background-color: currentcolor;
|
||||
transform: scalex(0);
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.header-navigation a {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header-navigation button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.card-left{
|
||||
background-color: white;
|
||||
}
|
||||
.card-right{
|
||||
background-color: cornsilk;
|
||||
}
|
||||
.container1{
|
||||
background-color: white;
|
||||
/*height: 500px;*/
|
||||
}
|
||||
.container2{
|
||||
/*background-color: #e6eef3;*/
|
||||
background: linear-gradient(rgb(253, 252, 251), rgb(226, 229, 231));
|
||||
/*height: 500px;*/
|
||||
color: #454647;
|
||||
}
|
||||
.container3{
|
||||
background: linear-gradient(rgb(253, 252, 251), rgb(226, 229, 231));
|
||||
/*height: 25em;*/
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
min-height: 70vh;
|
||||
}
|
||||
.block1{
|
||||
background: linear-gradient(rgb(253, 252, 251), rgb(226, 229, 231));
|
||||
height: 100%;
|
||||
}
|
||||
.block2{
|
||||
background: linear-gradient(rgb(249, 251, 252), rgb(207, 230, 241));
|
||||
}
|
||||
.button-green1{
|
||||
background: linear-gradient(90deg, rgb(80, 167, 186), rgb(103, 147, 174));
|
||||
/*color: rgb(255, 255, 255);*/
|
||||
color: white !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.heigh200{
|
||||
height: 200px;
|
||||
padding-top: 20px;
|
||||
padding-left: 30px;
|
||||
padding-bottom: 20px;
|
||||
/*margin: 10px;*/
|
||||
/*padding: 20px;*/
|
||||
}
|
||||
.text-right{
|
||||
text-align: right;
|
||||
}
|
||||
.text-left{
|
||||
text-align: left;
|
||||
}
|
||||
.padding-text-footer{
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
.img-footer{
|
||||
width: 6em;
|
||||
}
|
||||
.main{
|
||||
padding: 3em;
|
||||
}
|
||||
.card-white {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 15px 30px 0 rgba(0,0,0, 0.1);
|
||||
background-color: #fff;
|
||||
padding: 2.5rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 2rem;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.h1-grad{
|
||||
text-transform: capitalize;
|
||||
letter-spacing: 0.8px;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: clamp(3.4375rem, 3.25rem + 0.75vw, 4rem);
|
||||
background-color: #005baa;
|
||||
background-image: linear-gradient(45deg, #005baa, #000000);
|
||||
background-size: 100%;
|
||||
background-repeat: repeat;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
-moz-background-clip: text;
|
||||
-moz-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.hr1 {
|
||||
display: block;
|
||||
background: #005baa;
|
||||
height: 1rem;
|
||||
width: 6.25rem;
|
||||
border: none;
|
||||
margin: 1.125rem 0 1.875rem 0;
|
||||
}
|
||||
main a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
color: #717171;
|
||||
font-weight: 500;
|
||||
background: #fff;
|
||||
border-radius: 3.125rem;
|
||||
transition: 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-contact {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
color: #717171;
|
||||
font-weight: 500;
|
||||
background: #fff;
|
||||
border-radius: 3.125rem;
|
||||
transition: 0.3s ease-in-out;
|
||||
border: 2px solid #c2c2c2;
|
||||
margin-top: 2.188rem;
|
||||
padding: 0.625rem 1.875rem;
|
||||
}
|
||||
|
||||
.btn-contact:hover {
|
||||
border: 0.125rem solid #005baa;
|
||||
color: #005baa;
|
||||
}
|
||||
.img{
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 1.5em;
|
||||
padding: 2em;
|
||||
width: 100%;
|
||||
border-radius: 2.8em;
|
||||
}
|
||||
.img:hover{
|
||||
-webkit-transform: scale(1.2);
|
||||
-ms-transform: scale(1.2);
|
||||
transform: scale(1.2);
|
||||
transition: 1s ease;
|
||||
z-index: 1;
|
||||
}
|
||||
.swiper-slide {
|
||||
width: 18.75rem;
|
||||
height: 28.125rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
align-items: self-start;
|
||||
}
|
||||
|
||||
.swiper-slide h2 {
|
||||
color: #fff;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 0.625rem;
|
||||
padding: 0 0 0 1.563rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.swiper-slide p {
|
||||
color: #dadada;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 300;
|
||||
padding: 0 1.563rem;
|
||||
line-height: 1.6;
|
||||
font-size: 0.75rem;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 4;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.swiper-slide a {
|
||||
margin: 1.25rem 1.563rem 3.438rem 1.563rem;
|
||||
padding: 0.438em 1.875rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.swiper-slide a:hover {
|
||||
color: #005baa;
|
||||
}
|
||||
|
||||
.swiper-slide div {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
padding-bottom: 0.625rem;
|
||||
}
|
||||
.swiper-slide--one {
|
||||
background: linear-gradient(to top, #0f2027, #203a4300, #2c536400),
|
||||
url("https://images.unsplash.com/photo-1628944682084-831f35256163?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80")
|
||||
no-repeat 50% 50% / cover;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.swiper-slide--two {
|
||||
background: linear-gradient(to top, #0f2027, #203a4300, #2c536400),
|
||||
url("https://images.unsplash.com/photo-1570481662006-a3a1374699e8?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=765&q=80")
|
||||
no-repeat 50% 50% / cover;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.swiper-slide--three {
|
||||
background: linear-gradient(to top, #0f2027, #203a4300, #2c536400),
|
||||
url("https://images.unsplash.com/photo-1515309025403-4b0184873cef?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=735&q=80")
|
||||
no-repeat 50% 50% / cover;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.padd-card{
|
||||
padding: 1em;
|
||||
}
|
||||
.div-left{
|
||||
background-color: cadetblue;
|
||||
}
|
||||
.div-right{
|
||||
background-color: cornsilk;
|
||||
}
|
||||
|
||||
/*---------------------BIRD STRIKE---------------------*/
|
||||
.checkbox{
|
||||
width: 17x;
|
||||
height: 17px;
|
||||
border-radius: 10px
|
||||
}
|
||||
.class50{
|
||||
width: 50%;
|
||||
}
|
||||
.class100{
|
||||
width: 100%;
|
||||
}
|
||||
.show{
|
||||
display: block;
|
||||
}
|
||||
.hide{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.round-button{
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
border-radius: 100px !important;
|
||||
color: rebeccapurple !important;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
.row.paddless{
|
||||
margin-bottom: -10px !important;
|
||||
}
|
||||
input.checkbox{
|
||||
border-color: red;
|
||||
margin-bottom: -20px !important;
|
||||
margin-top: -20px !important;
|
||||
padding-bottom: -20px;
|
||||
right: auto;
|
||||
}
|
||||
.icon{
|
||||
margin: 26%;
|
||||
font-size: 70px;
|
||||
}
|
||||
|
||||
.opt1{
|
||||
margin-top: -5px;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
.opt-left{
|
||||
margin-left: -1.2em;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------START HERE ------------------*/
|
||||
.body{
|
||||
background-color: whitesmoke;
|
||||
/*height: 100%;*/
|
||||
}
|
||||
.footer1{
|
||||
background: rgb(51, 51, 51);
|
||||
color: white;
|
||||
height:100px;
|
||||
}
|
||||
.container4{
|
||||
background: linear-gradient(rgb(67, 67, 67), rgb(14, 14, 14));
|
||||
/*height: 25em;*/
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
.p-bird{
|
||||
font-size: 7em;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
padding-left: 0.5em;
|
||||
margin: 0;
|
||||
font-family: Tahoma, Geneva, Verdana, sans-serif;
|
||||
color: ghostwhite;
|
||||
}
|
||||
.p-strike{
|
||||
font-size: 7em;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
padding-left: 1.5em;
|
||||
margin: 0;
|
||||
font-family: Tahoma, Geneva, Verdana, sans-serif;
|
||||
color: ghostwhite;
|
||||
}
|
||||
.card-page1{
|
||||
border: none;
|
||||
box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px;
|
||||
/*box-shadow: rgba(0, 0, 0, 0.45) 0px 25px 20px -20px;*/
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.btn-nav{
|
||||
margin: 0;
|
||||
font-size: 5em;
|
||||
color: lightgray;
|
||||
}
|
||||
.btn-nav:hover{
|
||||
color: white;
|
||||
/*box-shadow: rgba(0, 0, 0, 0.4) 0px 30px 90px;*/
|
||||
}
|
||||
.btn-nav:active{
|
||||
color: dodgerblue;
|
||||
}
|
||||
.btn-nav-center{
|
||||
font-size: 2em;
|
||||
/*color: #434343;*/
|
||||
color: dodgerblue;
|
||||
}
|
||||
.btn-center-unactive{
|
||||
font-size: 2em;
|
||||
color: #434343;
|
||||
}
|
||||
.pad-img{
|
||||
/*padding: 2em;*/
|
||||
}
|
||||
.img-cctv{
|
||||
box-shadow: rgba(14, 30, 37, 0.12) 0px 2px 4px 0px, rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;
|
||||
border-radius: 10px;
|
||||
margin: 1.5em;
|
||||
}
|
||||
.btn-circle{
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
background-color: black;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
margin: 5%;
|
||||
border-radius: 50%;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0px 12px 28px 0px, rgba(0, 0, 0, 0.1) 0px 2px 4px 0px, rgba(255, 255, 255, 0.05) 0px 0px 0px 1px inset;
|
||||
}
|
||||
.pad-top{
|
||||
/*margin-top: -12px;*/
|
||||
/*margin-bottom: -40px;*/
|
||||
margin-top: -13px;
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
.pad-left{
|
||||
margin-top: -25px;
|
||||
/*margin-bottom: -20px;*/
|
||||
margin-right: -20px;
|
||||
}
|
||||
.pad-right{
|
||||
margin-top: -25px;
|
||||
/*margin-bottom: -20px;*/
|
||||
margin-left: -20px;
|
||||
}
|
||||
.pad-bottom{
|
||||
/*margin-top: -20px;*/
|
||||
/*margin-bottom: -20px;*/
|
||||
margin-top: -25px;
|
||||
/*margin-bottom: -12px;*/
|
||||
}
|
||||
|
||||
/*--------------------------------BUTTON-------------------------------*/
|
||||
.btn-round{
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
border-radius: 100%;
|
||||
background: white;
|
||||
border: 2px solid whitesmoke;
|
||||
box-shadow: 0 4px 4px rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
justify-content: center; /* Center horizontally */
|
||||
align-items: center; /* Center vertically */
|
||||
/*height: 100vh; !* Full viewport height *!*/
|
||||
}
|
||||
.outside{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.outside-logout{
|
||||
/*position: absolute;*/
|
||||
display: flex;
|
||||
/*text-align: right;*/
|
||||
margin-top: 3.5em;
|
||||
padding-bottom: 1em;
|
||||
justify-content: end;
|
||||
bottom: 10px; /* Adjust as needed */
|
||||
right: 10px; /* Adjust as needed */
|
||||
}
|
||||
|
||||
/*---------HEADER 2-------------------*/
|
||||
.p-bird2{
|
||||
font-size: 6rem;
|
||||
font-weight: lighter;
|
||||
text-align: left;
|
||||
padding-left: 0.5em;
|
||||
margin: 0;
|
||||
font-family: Tahoma, Geneva, Verdana, sans-serif;
|
||||
color: ghostwhite;
|
||||
}
|
||||
.hr-lines{
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
margin: 35px auto;
|
||||
text-align: center;
|
||||
font-size: 3.7em;
|
||||
color: white;
|
||||
/*z-index: 2;*/
|
||||
}
|
||||
.hr-lines:before {
|
||||
content:" ";
|
||||
height: 4px;
|
||||
width: 50px;
|
||||
background: red;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
/*stroke-dasharray: 10px;*/
|
||||
}
|
||||
.hr-lines:after{
|
||||
content:" ";
|
||||
height: 4px;
|
||||
width: 50px;
|
||||
background: red;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------5 BUTTON PLAY KONTEN -------------------------*/
|
||||
.btn-play1{
|
||||
text-decoration: none;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), to(#e7e7e7));
|
||||
background-image: -webkit-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
background-image: -moz-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
background-image: -ms-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
background-image: -o-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
/*color: #a7a7a7;*/
|
||||
color: black;
|
||||
/*width: 100%;*/
|
||||
/*padding-top: 100%;*/
|
||||
width: 4.2em;
|
||||
height: 4.2em;
|
||||
/*padding-top: 100%;*/
|
||||
position: relative;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 3px 8px #aaa, inset 0px 2px 3px #fff;
|
||||
border: solid 1px transparent;
|
||||
}
|
||||
|
||||
.btn-play1:before {
|
||||
content: "";
|
||||
display: block;
|
||||
background: #fff;
|
||||
border-top: 2px solid #ddd;
|
||||
position: absolute;
|
||||
/*top: -18px;*/
|
||||
/*left: -18px;*/
|
||||
/*bottom: -18px;*/
|
||||
/*right: -18px;*/
|
||||
z-index: -1;
|
||||
border-radius: 50%;
|
||||
box-shadow: inset 0px 8px 48px #ddd;
|
||||
}
|
||||
|
||||
.btn-play1:active {
|
||||
box-shadow: 0px 3px 8px #aaa inset, 0px 2px 3px #fff;
|
||||
}
|
||||
.btn-play1:hover {
|
||||
text-decoration: none;
|
||||
/*color: #555;*/
|
||||
color: black;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.icon1{
|
||||
margin: 27%;
|
||||
font-size: 2.2em;
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: 3px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
}
|
||||
.text-status1{
|
||||
/*padding-top: 1em;*/
|
||||
color: black;
|
||||
font-size: 2em;
|
||||
}
|
||||
.btn-mute{
|
||||
text-decoration: none;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), to(#e7e7e7));
|
||||
background-image: -webkit-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
background-image: -moz-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
background-image: -ms-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
background-image: -o-linear-gradient(top, #f7f7f7, #e7e7e7);
|
||||
/*color: #a7a7a7;*/
|
||||
color: black;
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
padding: 0.2em;
|
||||
/*width: 100%;*/
|
||||
/*padding-top: 100%;*/
|
||||
position: relative;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 3px 8px #aaa, inset 0px 2px 3px #fff;
|
||||
border: solid 1px transparent;
|
||||
}
|
||||
.pad-val-volume{
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
.pad-bar{
|
||||
padding: 0.5em;
|
||||
}
|
||||
/*----------------------------------------------------LOGIN------------------------------------*/
|
||||
.bg-img{
|
||||
background: url('../images/airport-terminal.jpg');
|
||||
/*background: url('../images/airport-terminal-bw.jpg');*/
|
||||
height: 100vh;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.bg-img:after{
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: rgb(40 67 73 / 40%);
|
||||
}
|
||||
.content{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
border-radius: 15px;
|
||||
z-index: 999;
|
||||
text-align: center;
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 60px 32px;
|
||||
width: 370px;
|
||||
transform: translate(-50%,-50%);
|
||||
background: rgba(255,255,255,0.04);
|
||||
box-shadow: -1px 4px 28px 0px rgba(0,0,0,0.75);
|
||||
}
|
||||
.content header{
|
||||
color: white;
|
||||
font-size: 33px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 35px 0;
|
||||
font-family: 'Montserrat',sans-serif;
|
||||
}
|
||||
.field{
|
||||
position: relative;
|
||||
height: 45px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
background: rgba(255,255,255,0.94);
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
/*border-radius: 4px;*/
|
||||
}
|
||||
.field span{
|
||||
color: #222;
|
||||
width: 40px;
|
||||
line-height: 45px;
|
||||
}
|
||||
.field input{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
color: #222;
|
||||
font-size: 16px;
|
||||
font-family: 'Poppins',sans-serif;
|
||||
padding: 10px;
|
||||
}
|
||||
.space{
|
||||
margin-top: 16px;
|
||||
}
|
||||
.showw{
|
||||
position: absolute;
|
||||
right: 13px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #222;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
font-family: 'Montserrat',sans-serif;
|
||||
}
|
||||
.pass-key:valid ~ .show{
|
||||
display: block;
|
||||
}
|
||||
.pass{
|
||||
text-align: left;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.pass a{
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-family: 'Poppins',sans-serif;
|
||||
}
|
||||
.pass:hover a{
|
||||
text-decoration: underline;
|
||||
}
|
||||
.field input[type="submit"]{
|
||||
background: #3498db;
|
||||
border: 1px solid #2691d9;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
letter-spacing: 1px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
font-family: 'Montserrat',sans-serif;
|
||||
}
|
||||
.field input[type="submit"]:hover{
|
||||
background: #2691d9;
|
||||
}
|
||||
.login{
|
||||
color: white;
|
||||
margin: 20px 0;
|
||||
font-family: 'Poppins',sans-serif;
|
||||
}
|
||||
.input-rad{
|
||||
border-radius: 4px;
|
||||
}
|
||||
.padding-lock{
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.padding-btn{
|
||||
padding: 0;
|
||||
}
|
||||
.pad-br{
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.div-disabled{
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.output{
|
||||
padding-left: 20%;
|
||||
}
|
||||
.pad-menu{
|
||||
padding-right: 20px;
|
||||
}
|
||||
.container-setting{
|
||||
background: linear-gradient(rgb(253, 252, 251), rgb(226, 229, 231));
|
||||
min-height: 70vh;
|
||||
}
|
||||
.p-title{
|
||||
font-size: 2.5em !important;
|
||||
}
|
||||
.bg-gray{
|
||||
background: linear-gradient(rgb(253, 252, 251), rgb(226, 229, 231));
|
||||
}
|
||||
.card-shadow{
|
||||
box-shadow: rgba(0, 0, 0, 0.45) 0px 25px 20px -20px;
|
||||
}
|
||||
BIN
Html/html/public/webfonts/fa-brands-400.ttf
Normal file
BIN
Html/html/public/webfonts/fa-brands-400.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-brands-400.woff2
Normal file
BIN
Html/html/public/webfonts/fa-brands-400.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-duotone-900.ttf
Normal file
BIN
Html/html/public/webfonts/fa-duotone-900.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-duotone-900.woff2
Normal file
BIN
Html/html/public/webfonts/fa-duotone-900.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-light-300.ttf
Normal file
BIN
Html/html/public/webfonts/fa-light-300.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-light-300.woff2
Normal file
BIN
Html/html/public/webfonts/fa-light-300.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-regular-400.ttf
Normal file
BIN
Html/html/public/webfonts/fa-regular-400.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-regular-400.woff2
Normal file
BIN
Html/html/public/webfonts/fa-regular-400.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-light-300.ttf
Normal file
BIN
Html/html/public/webfonts/fa-sharp-light-300.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-light-300.woff2
Normal file
BIN
Html/html/public/webfonts/fa-sharp-light-300.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-regular-400.ttf
Normal file
BIN
Html/html/public/webfonts/fa-sharp-regular-400.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-regular-400.woff2
Normal file
BIN
Html/html/public/webfonts/fa-sharp-regular-400.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-solid-900.ttf
Normal file
BIN
Html/html/public/webfonts/fa-sharp-solid-900.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-solid-900.woff2
Normal file
BIN
Html/html/public/webfonts/fa-sharp-solid-900.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-thin-100.ttf
Normal file
BIN
Html/html/public/webfonts/fa-sharp-thin-100.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-sharp-thin-100.woff2
Normal file
BIN
Html/html/public/webfonts/fa-sharp-thin-100.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-solid-900.ttf
Normal file
BIN
Html/html/public/webfonts/fa-solid-900.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-solid-900.woff2
Normal file
BIN
Html/html/public/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-thin-100.ttf
Normal file
BIN
Html/html/public/webfonts/fa-thin-100.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-thin-100.woff2
Normal file
BIN
Html/html/public/webfonts/fa-thin-100.woff2
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-v4compatibility.ttf
Normal file
BIN
Html/html/public/webfonts/fa-v4compatibility.ttf
Normal file
Binary file not shown.
BIN
Html/html/public/webfonts/fa-v4compatibility.woff2
Normal file
BIN
Html/html/public/webfonts/fa-v4compatibility.woff2
Normal file
Binary file not shown.
256
Html/html/setting.html
Normal file
256
Html/html/setting.html
Normal file
@@ -0,0 +1,256 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Bird Deterrent System</title>
|
||||
<link rel="stylesheet" type="text/css" href="public/style/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="public/style/bootstrap.min.css">
|
||||
<script src="public/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="public/style/jquery.dataTables.min.css">
|
||||
<script src="public/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="public/js/jquery.dataTables.min.js"></script>
|
||||
<script src="public/js/all.min.js"></script>
|
||||
<link rel="stylesheet" href="public/style/all.min.css">
|
||||
<script src="setting.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="onload()">
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark text-light container4">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand p-title" href="index.html">Bird Deterrent System</a>
|
||||
|
||||
<!-- Toggler/collapsible Button -->
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<!-- Collapsible Navbar -->
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item pad-menu">
|
||||
<a class="nav-link" href="setting.html">Setting</a>
|
||||
</li>
|
||||
<li class="nav-item pad-menu">
|
||||
<form action="/logout" method="get">
|
||||
<button class="btn btn-outline-light" type="submit">Logout</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- SECTION 2 -->
|
||||
<div class="container-fluid container-setting">
|
||||
<div class="container">
|
||||
<div class="card mt-5 card-shadow">
|
||||
<div class="card-header bg-secondary text-light">
|
||||
<h5 class="text-md-center">Audio Files</h5>
|
||||
</div>
|
||||
<div class="card-body bg-gray">
|
||||
<form action="/setting/audiofile" method="post">
|
||||
<!-- PRESET 1-->
|
||||
<div class="row mt--2">
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<p>Preset 1</p>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<select id="preset1" class="form-control class100">
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRESET 2-->
|
||||
<div class="row mt-2">
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<p>Preset 2</p>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<select id="preset2" class="form-control class100">
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRESET 3-->
|
||||
<div class="row mt-2">
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<p>Preset 3</p>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<select id="preset3" class="form-control class100">
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRESET 4-->
|
||||
<div class="row mt-2">
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<p>Preset 4</p>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<select id="preset4" class="form-control class100">
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRESET 5-->
|
||||
<div class="row mt-2">
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<p>Preset 5</p>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||
<select id="preset5" class="form-control class100">
|
||||
<option>Option 1</option>
|
||||
<option>Option 2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-6"></div>
|
||||
<div class="col-6">
|
||||
<button id="save_audio" type="submit" class="btn btn-primary class100" onclick="save_audio()">SAVE</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-5 card-shadow">
|
||||
<div class="card-header bg-secondary text-light">
|
||||
<h5 class="text-center"> Upload Audio</h5>
|
||||
</div>
|
||||
<div class="card-body bg-gray">
|
||||
<form action="/setting/uploadaudiofile" method="post" enctype="multipart/form-data">
|
||||
<div class="row mt-2">
|
||||
<div class="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
|
||||
<p> Upload audio files</p>
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-4 col-lg-4 col-xl-4">
|
||||
<input class="form-control" type="file" name="file" title="Select Audio File">
|
||||
</div>
|
||||
<div class="col-6 col-sm-6 col-md-2 col-lg-2 col-xl-2">
|
||||
<button id="uploadd_file" type="submit" class="btn btn-dark class100">Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card mt-5 card-shadow">
|
||||
<div class="card-header bg-secondary text-light ">
|
||||
<h5 class="text-center">Camera</h5>
|
||||
</div>
|
||||
<div class="card-body bg-gray">
|
||||
<form action="/setting/camera" method="post">
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<p>IP Address</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input id="setting_ip" class="form-control" title="IP Address">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<p>Port</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input id="setting_port" class="form-control" title="Port">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<p>Username</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input id="setting_username" class="form-control" title="Username">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<p>Password</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="input-group">
|
||||
<input type="password" id="setting_password" class="form-control" title="Password">
|
||||
<span class="input-group-text" onclick="cameraPassword()">
|
||||
<i class="fa-solid fa-eye" id="icon_camera"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-6"></div>
|
||||
<div class="col-6">
|
||||
<button id="save_camera" type="submit" class="btn btn-primary class100" onclick="save_camera()">SAVE</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-5 card-shadow">
|
||||
<div class="card-header bg-secondary text-light">
|
||||
<h5 class="text-center">Login</h5>
|
||||
</div>
|
||||
<div class="card-body bg-gray">
|
||||
<form action="/setting/weblogin" method="post">
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<p>Username</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<input id="login_username" class="form-control" title="Username">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<p>Password</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="input-group">
|
||||
<input type="password" id="edit_password" class="form-control" title="Password">
|
||||
<span class="input-group-text" onclick="showPassword()">
|
||||
<i class="fa-solid fa-eye" id="icon_password"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-6">
|
||||
<p>Confirm Password</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="input-group">
|
||||
<input type="password" id="confirm_password" class="form-control" title="Confirm Password">
|
||||
<span class="input-group-text" onclick="showConfirm()">
|
||||
<i class="fa-solid fa-eye" id="icon_confirm"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-6"></div>
|
||||
<div class="col-6">
|
||||
<button id="save_login" type="submit" class="btn btn-primary class100" onclick="save_login()">SAVE</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SECTION 3 -->
|
||||
<div class="container-fluid footer1 outside">
|
||||
<p>2024 Copyright © Galva Technologies. All rights reserved.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
111
Html/html/setting.js
Normal file
111
Html/html/setting.js
Normal file
@@ -0,0 +1,111 @@
|
||||
// script for setting.html start here
|
||||
async function onload(){
|
||||
const resp = await fetch("/setting");
|
||||
if (resp.status === 200) {
|
||||
/**
|
||||
* @type {Object}
|
||||
* @property {String[]} AudioFiles
|
||||
* @property {String} AudioFile1
|
||||
* @property {String} AudioFile2
|
||||
* @property {String} AudioFile3
|
||||
* @property {String} AudioFile4
|
||||
* @property {String} AudioFile5
|
||||
* @property {String} CameraIP
|
||||
* @property {String} CameraPort
|
||||
* @property {String} CameraUsername
|
||||
* @property {String} CameraPassword
|
||||
* @property {String} LoginUsername
|
||||
* @property {String} LoginPassword
|
||||
*/
|
||||
const data = await resp.json();
|
||||
fill_select(1, data["AudioFiles"]);
|
||||
fill_select(2, data["AudioFiles"]);
|
||||
fill_select(3, data["AudioFiles"]);
|
||||
fill_select(4, data["AudioFiles"]);
|
||||
fill_select(5, data["AudioFiles"]);
|
||||
|
||||
$("#preset1").val(data["AudioFile1"]);
|
||||
$("#preset2").val(data["AudioFile2"]);
|
||||
$("#preset3").val(data["AudioFile3"]);
|
||||
$("#preset4").val(data["AudioFile4"]);
|
||||
$("#preset5").val(data["AudioFile5"]);
|
||||
|
||||
$("#setting_ip").val(data["CameraIP"]);
|
||||
$("#setting_port").val(data["CameraPort"]);
|
||||
$("#setting_username").val(data["CameraUsername"]);
|
||||
$("#setting_password").val(data["CameraPassword"]);
|
||||
|
||||
$("#login_username").val(data["LoginUsername"]);
|
||||
$("#edit_password").val(data["LoginPassword"]);
|
||||
$("#confirm_password").val(data["LoginPassword"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill select with values
|
||||
* @param {number} index start from 1
|
||||
* @param {String[]} values array of values
|
||||
*/
|
||||
function fill_select(index, values){
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {HTMLSelectElement}
|
||||
*/
|
||||
let preset = document.getElementById("preset"+index);
|
||||
preset.innerHTML = "";
|
||||
if (values!=null && values.length>0){
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const element = values[i];
|
||||
let option = document.createElement("option");
|
||||
option.value = element;
|
||||
option.innerText = element;
|
||||
preset.appendChild(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cameraPassword() {
|
||||
const passwordField = document.getElementById('setting_password');
|
||||
const icon = document.getElementById('icon_camera');
|
||||
|
||||
if (passwordField.type === 'password') {
|
||||
passwordField.type = 'text';
|
||||
icon.classList.remove('fa-eye');
|
||||
icon.classList.add('fa-eye-slash');
|
||||
} else {
|
||||
passwordField.type = 'password';
|
||||
icon.classList.remove('fa-eye-slash');
|
||||
icon.classList.add('fa-eye');
|
||||
}
|
||||
}
|
||||
|
||||
function showPassword() {
|
||||
const passwordField = document.getElementById('edit_password');
|
||||
const icon = document.getElementById('icon_password');
|
||||
|
||||
if (passwordField.type === 'password') {
|
||||
passwordField.type = 'text';
|
||||
icon.classList.remove('fa-eye');
|
||||
icon.classList.add('fa-eye-slash');
|
||||
} else {
|
||||
passwordField.type = 'password';
|
||||
icon.classList.remove('fa-eye-slash');
|
||||
icon.classList.add('fa-eye');
|
||||
}
|
||||
}
|
||||
|
||||
function showConfirm() {
|
||||
const passwordField = document.getElementById('confirm_password');
|
||||
const icon = document.getElementById('icon_confirm');
|
||||
|
||||
if (passwordField.type === 'password') {
|
||||
passwordField.type = 'text';
|
||||
icon.classList.remove('fa-eye');
|
||||
icon.classList.add('fa-eye-slash');
|
||||
} else {
|
||||
passwordField.type = 'password';
|
||||
icon.classList.remove('fa-eye-slash');
|
||||
icon.classList.add('fa-eye');
|
||||
}
|
||||
}
|
||||
24
config.properties
Normal file
24
config.properties
Normal file
@@ -0,0 +1,24 @@
|
||||
#Fri Nov 08 16:52:01 WIB 2024
|
||||
AudioFile01=elangWav.wav
|
||||
AudioFile02=gunshotsWav.wav
|
||||
AudioFile03=pinkNoiseWav.wav
|
||||
AudioFile04=04.mp3
|
||||
AudioFile05=05.mp3
|
||||
AudioVolumeOutput=100
|
||||
Camera_Rtsp_path=/axis-media/media.amp
|
||||
Camera_ip=192.168.10.17
|
||||
Camera_password=password
|
||||
Camera_port=80
|
||||
Camera_user=root
|
||||
PanTiltID=1
|
||||
SerialBaudRate=9600
|
||||
SerialPort=/dev/ttyUSB0
|
||||
WebHost=0.0.0.0
|
||||
WebPassword=bandara
|
||||
WebPort=8080
|
||||
WebUsername=admin
|
||||
audiofile1=
|
||||
audiofile2=
|
||||
audiofile3=
|
||||
audiofile4=
|
||||
audiofile5=
|
||||
1722
hs_err_pid16944.log
Normal file
1722
hs_err_pid16944.log
Normal file
File diff suppressed because one or more lines are too long
1721
hs_err_pid18892.log
Normal file
1721
hs_err_pid18892.log
Normal file
File diff suppressed because one or more lines are too long
1727
hs_err_pid23232.log
Normal file
1727
hs_err_pid23232.log
Normal file
File diff suppressed because one or more lines are too long
2001
hs_err_pid29656.log
Normal file
2001
hs_err_pid29656.log
Normal file
File diff suppressed because one or more lines are too long
1722
hs_err_pid32272.log
Normal file
1722
hs_err_pid32272.log
Normal file
File diff suppressed because one or more lines are too long
1723
hs_err_pid39288.log
Normal file
1723
hs_err_pid39288.log
Normal file
File diff suppressed because one or more lines are too long
BIN
lib/linux-aarch64/libbass.so
Normal file
BIN
lib/linux-aarch64/libbass.so
Normal file
Binary file not shown.
BIN
lib/linux-armhf/libbass.so
Normal file
BIN
lib/linux-armhf/libbass.so
Normal file
Binary file not shown.
BIN
lib/linux-x86-64/libbass.so
Normal file
BIN
lib/linux-x86-64/libbass.so
Normal file
Binary file not shown.
BIN
lib/linux-x86/libbass.so
Normal file
BIN
lib/linux-x86/libbass.so
Normal file
Binary file not shown.
BIN
lib/win32-arm64/bass.dll
Normal file
BIN
lib/win32-arm64/bass.dll
Normal file
Binary file not shown.
BIN
lib/win32-x86-64/bass.dll
Normal file
BIN
lib/win32-x86-64/bass.dll
Normal file
Binary file not shown.
BIN
lib/win32-x86/bass.dll
Normal file
BIN
lib/win32-x86/bass.dll
Normal file
Binary file not shown.
63
pom.xml
Normal file
63
pom.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?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>id.co.gtc</groupId>
|
||||
<artifactId>BirdStrikeSoetta</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacv-platform</artifactId>
|
||||
<version>1.5.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.javalin</groupId>
|
||||
<artifactId>javalin</artifactId>
|
||||
<version> 6.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>5.15.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tinylog</groupId>
|
||||
<artifactId>tinylog-impl</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fazecast</groupId>
|
||||
<artifactId>jSerialComm</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.16</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
34
simplelogger.properties
Normal file
34
simplelogger.properties
Normal file
@@ -0,0 +1,34 @@
|
||||
# SLF4J's SimpleLogger configuration file
|
||||
# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
|
||||
|
||||
# Default logging detail level for all instances of SimpleLogger.
|
||||
# Must be one of ("trace", "debug", "info", "warn", or "error").
|
||||
# If not specified, defaults to "info".
|
||||
org.slf4j.simpleLogger.defaultLogLevel=warn
|
||||
|
||||
# Logging detail level for a SimpleLogger instance named "xxxxx".
|
||||
# Must be one of ("trace", "debug", "info", "warn", or "error").
|
||||
# If not specified, the default logging detail level is used.
|
||||
#org.slf4j.simpleLogger.log.xxxxx=
|
||||
|
||||
# Set to true if you want the current date and time to be included in output messages.
|
||||
# Default is false, and will output the number of milliseconds elapsed since startup.
|
||||
#org.slf4j.simpleLogger.showDateTime=false
|
||||
|
||||
# The date and time format to be used in the output messages.
|
||||
# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
|
||||
# If the format is not specified or is invalid, the default format is used.
|
||||
# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
|
||||
#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
|
||||
|
||||
# Set to true if you want to output the current thread name.
|
||||
# Defaults to true.
|
||||
#org.slf4j.simpleLogger.showThreadName=true
|
||||
|
||||
# Set to true if you want the Logger instance name to be included in output messages.
|
||||
# Defaults to true.
|
||||
#org.slf4j.simpleLogger.showLogName=true
|
||||
|
||||
# Set to true if you want the last component of the name to be included in output messages.
|
||||
# Defaults to false.
|
||||
#org.slf4j.simpleLogger.showShortLogName=false
|
||||
14
src/main/java/Audio/AudioFileProperties.java
Normal file
14
src/main/java/Audio/AudioFileProperties.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package Audio;
|
||||
|
||||
|
||||
public class AudioFileProperties {
|
||||
public final int handle;
|
||||
public final String filename;
|
||||
public long Length;
|
||||
public double duration;
|
||||
public AudioFileProperties(int handle, String filename){
|
||||
this.handle = handle;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
}
|
||||
196
src/main/java/Audio/AudioPlayer.java
Normal file
196
src/main/java/Audio/AudioPlayer.java
Normal file
@@ -0,0 +1,196 @@
|
||||
package Audio;
|
||||
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
public class AudioPlayer {
|
||||
Bass bass;
|
||||
int deviceid = -1;
|
||||
boolean inited = false;
|
||||
|
||||
int playbackhandle = 0;
|
||||
float playbackvolume = 1.0f;
|
||||
|
||||
public AudioPlayer(){
|
||||
bass = Bass.Instance;
|
||||
Logger.info("Bass Version = {}", Integer.toHexString(bass.BASS_GetVersion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload Bass
|
||||
*/
|
||||
public void Unload(){
|
||||
if (inited){
|
||||
Logger.info("Freeing Device {}", deviceid);
|
||||
bass.BASS_SetDevice(deviceid);
|
||||
bass.BASS_Free();
|
||||
}
|
||||
deviceid = -1;
|
||||
inited = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect Output Devices
|
||||
*/
|
||||
public void DetectOutputDevices(){
|
||||
Logger.info("Detecting Output Devices...");
|
||||
int ii = 1;
|
||||
while (true){
|
||||
Bass.BASS_DEVICEINFO info = new Bass.BASS_DEVICEINFO();
|
||||
if (bass.BASS_GetDeviceInfo(ii, info)){
|
||||
Logger.info("Device {} = {}, flags = {}", ii, info.name, Integer.toHexString(info.flags));
|
||||
ii++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open Output Device
|
||||
* @param device device id, starts from 1
|
||||
* @param freq output frequency
|
||||
* @return true if success
|
||||
*/
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public boolean OpenDevice(int device, int freq){
|
||||
int flag = Bass.BASS_DEVICE_REINIT | Bass.BASS_DEVICE_16BITS | Bass.BASS_DEVICE_MONO | Bass.BASS_DEVICE_FREQ;
|
||||
boolean success = bass.BASS_Init(device, freq, flag);
|
||||
if (success){
|
||||
Logger.info("Device {} opened successfully", device);
|
||||
deviceid = device;
|
||||
inited = true;
|
||||
} else {
|
||||
Logger.error("Failed to open device {}, Error Code {}", device, bass.BASS_ErrorGetCode());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Master Volume
|
||||
* @param value volume value, 0-100
|
||||
*/
|
||||
public void setMasterVolume(int value){
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
if (inited){
|
||||
bass.BASS_SetDevice(deviceid);
|
||||
if (!bass.BASS_SetVolume(value/100.0f)){
|
||||
Logger.error("Failed to set Master Volume to {}, Error Code {}", value, bass.BASS_ErrorGetCode());
|
||||
} else Logger.info("Master Volume set to {}", value);
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Master Volume
|
||||
* @return 0 - 100, or -1 if failed
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public int getMasterVolume(){
|
||||
if (inited){
|
||||
bass.BASS_SetDevice(deviceid);
|
||||
float vol = bass.BASS_GetVolume();
|
||||
if (vol>=0 && vol<=1){
|
||||
return (int)(vol*100);
|
||||
}
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getPlaybackvolume(){
|
||||
if (playbackvolume<0)
|
||||
return 0;
|
||||
else if (playbackvolume>1.0f)
|
||||
return 100;
|
||||
else
|
||||
return (int)(playbackvolume*100);
|
||||
}
|
||||
|
||||
public void setPlaybackvolume(int value){
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
playbackvolume = value/100.0f;
|
||||
if (playbackhandle!=0){
|
||||
bass.BASS_ChannelSetAttribute(playbackhandle, Bass.BASS_ATTRIB_VOL, playbackvolume);
|
||||
}
|
||||
}
|
||||
|
||||
private float lastplaybackvolume = 1.0f;
|
||||
|
||||
public void Mute(){
|
||||
lastplaybackvolume = playbackvolume;
|
||||
setPlaybackvolume(0);
|
||||
}
|
||||
|
||||
public void Unmute(){
|
||||
setPlaybackvolume((int)lastplaybackvolume*100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open Audio File
|
||||
* @param ff audio file name to open
|
||||
* @return AudioFileProperties object or null if failed
|
||||
*/
|
||||
public AudioFileProperties OpenAudioFile(File ff){
|
||||
if (inited){
|
||||
int handle = bass.BASS_StreamCreateFile(false, ff.getAbsolutePath(), 0, 0,0);
|
||||
if (handle!=0){
|
||||
Logger.info("Audio file {} opened successfully", ff.getName());
|
||||
AudioFileProperties prop = new AudioFileProperties(handle, ff.getName());
|
||||
prop.Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE);
|
||||
prop.duration = bass.BASS_ChannelBytes2Seconds(handle, prop.Length);
|
||||
return prop;
|
||||
} else Logger.error("Failed to open audio file {}, Error Code {}", ff.getAbsolutePath(), bass.BASS_ErrorGetCode());
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Audio File
|
||||
* @param prop AudioFileProperties object to close
|
||||
*/
|
||||
public void CloseAudioFile(AudioFileProperties prop) {
|
||||
playbackhandle = 0;
|
||||
if (inited) {
|
||||
if (prop != null) {
|
||||
if (!bass.BASS_StreamFree(prop.handle)) {
|
||||
{
|
||||
Logger.error("Failed to close audio file {}, Error Code {}", prop.filename, bass.BASS_ErrorGetCode());
|
||||
}
|
||||
} else Logger.info("Audio file {} closed successfully", prop.filename);
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayAudioFile(AudioFileProperties prop, boolean looping, PlaybackEvent event){
|
||||
if (inited){
|
||||
if (prop!=null){
|
||||
if (bass.BASS_ChannelStart(prop.handle)){
|
||||
playbackhandle = prop.handle;
|
||||
bass.BASS_ChannelSetAttribute(prop.handle, Bass.BASS_ATTRIB_VOL, playbackvolume);
|
||||
if (looping) bass.BASS_ChannelFlags(prop.handle, Bass.BASS_SAMPLE_LOOP, Bass.BASS_SAMPLE_LOOP);
|
||||
if (event!=null) event.onPlaybackStart(prop);
|
||||
int devfailsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_DEV_FAIL,0, (handle, channel, data, user)->{
|
||||
if (event!=null) event.onPlaybackFailure(prop, "Device Failure");
|
||||
}, null);
|
||||
if (devfailsync==0) Logger.error("Failed to set Device Failure Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
int endsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_END, 0, (handle, channel, data, user)->{
|
||||
if (looping) {
|
||||
if (event!=null) event.onPlaybackLooped(prop);
|
||||
} else if (event!=null) event.onPlaybackFinished(prop);
|
||||
}, null);
|
||||
if (endsync==0) Logger.error("Failed to set End Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
} else {
|
||||
if (event!=null) event.onPlaybackFailure(prop, String.format("Failed to play audio file %s, Error Code %d", prop.filename, bass.BASS_ErrorGetCode()));
|
||||
}
|
||||
} else {
|
||||
if (event!=null) event.onPlaybackFailure(null, "AudioFileProperties is null");
|
||||
}
|
||||
} else {
|
||||
if (event!=null) event.onPlaybackFailure(prop, "AudioPlayer not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
790
src/main/java/Audio/Bass.java
Normal file
790
src/main/java/Audio/Bass.java
Normal file
@@ -0,0 +1,790 @@
|
||||
package Audio;
|
||||
|
||||
import com.sun.jna.*;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface Bass extends Library {
|
||||
|
||||
Bass Instance = (Bass) Native.load("bass", Bass.class);
|
||||
int BASSVERSION = 0x204; // API version
|
||||
String BASSVERSIONTEXT = "2.4";
|
||||
|
||||
// Error codes returned by BASS_ErrorGetCode
|
||||
int BASS_OK = 0; // all is OK
|
||||
int BASS_ERROR_MEM = 1; // memory error
|
||||
int BASS_ERROR_FILEOPEN = 2; // can't open the file
|
||||
int BASS_ERROR_DRIVER = 3; // can't find a free/valid driver
|
||||
int BASS_ERROR_BUFLOST = 4; // the sample buffer was lost
|
||||
int BASS_ERROR_HANDLE = 5; // invalid handle
|
||||
int BASS_ERROR_FORMAT = 6; // unsupported sample format
|
||||
int BASS_ERROR_POSITION = 7; // invalid position
|
||||
int BASS_ERROR_INIT = 8; // BASS_Init has not been successfully called
|
||||
int BASS_ERROR_START = 9; // BASS_Start has not been successfully called
|
||||
int BASS_ERROR_SSL = 10; // SSL/HTTPS support isn't available
|
||||
int BASS_ERROR_REINIT = 11; // device needs to be reinitialized
|
||||
int BASS_ERROR_ALREADY = 14; // already initialized/paused/whatever
|
||||
int BASS_ERROR_NOTAUDIO = 17; // file does not contain audio
|
||||
int BASS_ERROR_NOCHAN = 18; // can't get a free channel
|
||||
int BASS_ERROR_ILLTYPE = 19; // an illegal type was specified
|
||||
int BASS_ERROR_ILLPARAM = 20; // an illegal parameter was specified
|
||||
int BASS_ERROR_NO3D = 21; // no 3D support
|
||||
int BASS_ERROR_NOEAX = 22; // no EAX support
|
||||
int BASS_ERROR_DEVICE = 23; // illegal device number
|
||||
int BASS_ERROR_NOPLAY = 24; // not playing
|
||||
int BASS_ERROR_FREQ = 25; // illegal sample rate
|
||||
int BASS_ERROR_NOTFILE = 27; // the stream is not a file stream
|
||||
int BASS_ERROR_NOHW = 29; // no hardware voices available
|
||||
int BASS_ERROR_EMPTY = 31; // the file has no sample data
|
||||
int BASS_ERROR_NONET = 32; // no internet connection could be opened
|
||||
int BASS_ERROR_CREATE = 33; // couldn't create the file
|
||||
int BASS_ERROR_NOFX = 34; // effects are not available
|
||||
int BASS_ERROR_NOTAVAIL = 37; // requested data/action is not available
|
||||
int BASS_ERROR_DECODE = 38; // the channel is a "decoding channel"
|
||||
int BASS_ERROR_DX = 39; // a sufficient DirectX version is not installed
|
||||
int BASS_ERROR_TIMEOUT = 40; // connection timedout
|
||||
int BASS_ERROR_FILEFORM = 41; // unsupported file format
|
||||
int BASS_ERROR_SPEAKER = 42; // unavailable speaker
|
||||
int BASS_ERROR_VERSION = 43; // invalid BASS version (used by add-ons)
|
||||
int BASS_ERROR_CODEC = 44; // codec is not available/supported
|
||||
int BASS_ERROR_ENDED = 45; // the channel/file has ended
|
||||
int BASS_ERROR_BUSY = 46; // the device is busy
|
||||
int BASS_ERROR_UNSTREAMABLE = 47; // unstreamable file
|
||||
int BASS_ERROR_PROTOCOL = 48; // unsupported protocol
|
||||
int BASS_ERROR_DENIED = 49; // access denied
|
||||
int BASS_ERROR_UNKNOWN = -1; // some other mystery problem
|
||||
|
||||
int BASS_ERROR_JAVA_CLASS = 500; // object class problem
|
||||
|
||||
// BASS_SetConfig options
|
||||
int BASS_CONFIG_BUFFER = 0;
|
||||
int BASS_CONFIG_UPDATEPERIOD = 1;
|
||||
int BASS_CONFIG_GVOL_SAMPLE = 4;
|
||||
int BASS_CONFIG_GVOL_STREAM = 5;
|
||||
int BASS_CONFIG_GVOL_MUSIC = 6;
|
||||
int BASS_CONFIG_CURVE_VOL = 7;
|
||||
int BASS_CONFIG_CURVE_PAN = 8;
|
||||
int BASS_CONFIG_FLOATDSP = 9;
|
||||
int BASS_CONFIG_3DALGORITHM = 10;
|
||||
int BASS_CONFIG_NET_TIMEOUT = 11;
|
||||
int BASS_CONFIG_NET_BUFFER = 12;
|
||||
int BASS_CONFIG_PAUSE_NOPLAY = 13;
|
||||
int BASS_CONFIG_NET_PREBUF = 15;
|
||||
int BASS_CONFIG_NET_PASSIVE = 18;
|
||||
int BASS_CONFIG_REC_BUFFER = 19;
|
||||
int BASS_CONFIG_NET_PLAYLIST = 21;
|
||||
int BASS_CONFIG_MUSIC_VIRTUAL = 22;
|
||||
int BASS_CONFIG_VERIFY = 23;
|
||||
int BASS_CONFIG_UPDATETHREADS = 24;
|
||||
int BASS_CONFIG_DEV_BUFFER = 27;
|
||||
int BASS_CONFIG_DEV_DEFAULT = 36;
|
||||
int BASS_CONFIG_NET_READTIMEOUT = 37;
|
||||
int BASS_CONFIG_HANDLES = 41;
|
||||
int BASS_CONFIG_SRC = 43;
|
||||
int BASS_CONFIG_SRC_SAMPLE = 44;
|
||||
int BASS_CONFIG_ASYNCFILE_BUFFER = 45;
|
||||
int BASS_CONFIG_OGG_PRESCAN = 47;
|
||||
int BASS_CONFIG_DEV_NONSTOP = 50;
|
||||
int BASS_CONFIG_VERIFY_NET = 52;
|
||||
int BASS_CONFIG_DEV_PERIOD = 53;
|
||||
int BASS_CONFIG_FLOAT = 54;
|
||||
int BASS_CONFIG_NET_SEEK = 56;
|
||||
int BASS_CONFIG_AM_DISABLE = 58;
|
||||
int BASS_CONFIG_NET_PLAYLIST_DEPTH = 59;
|
||||
int BASS_CONFIG_NET_PREBUF_WAIT = 60;
|
||||
int BASS_CONFIG_ANDROID_SESSIONID = 62;
|
||||
int BASS_CONFIG_ANDROID_AAUDIO = 67;
|
||||
int BASS_CONFIG_SAMPLE_ONEHANDLE = 69;
|
||||
int BASS_CONFIG_DEV_TIMEOUT = 70;
|
||||
int BASS_CONFIG_NET_META = 71;
|
||||
int BASS_CONFIG_NET_RESTRATE = 72;
|
||||
int BASS_CONFIG_REC_DEFAULT = 73;
|
||||
int BASS_CONFIG_NORAMP = 74;
|
||||
|
||||
// BASS_SetConfigPtr options
|
||||
int BASS_CONFIG_NET_AGENT = 16;
|
||||
int BASS_CONFIG_NET_PROXY = 17;
|
||||
int BASS_CONFIG_LIBSSL = 64;
|
||||
int BASS_CONFIG_FILENAME = 75;
|
||||
|
||||
int BASS_CONFIG_THREAD = 0x40000000; // flag: thread-specific setting
|
||||
|
||||
// BASS_Init flags
|
||||
int BASS_DEVICE_8BITS = 1; // unused
|
||||
int BASS_DEVICE_MONO = 2; // mono
|
||||
int BASS_DEVICE_3D = 4; // unused
|
||||
int BASS_DEVICE_16BITS = 8; // limit output to 16-bit
|
||||
int BASS_DEVICE_REINIT = 128; // reinitialize
|
||||
int BASS_DEVICE_LATENCY = 0x100; // unused
|
||||
int BASS_DEVICE_SPEAKERS = 0x800; // force enabling of speaker assignment
|
||||
int BASS_DEVICE_NOSPEAKER = 0x1000; // ignore speaker arrangement
|
||||
int BASS_DEVICE_DMIX = 0x2000; // use ALSA "dmix" plugin
|
||||
int BASS_DEVICE_FREQ = 0x4000; // set device sample rate
|
||||
int BASS_DEVICE_STEREO = 0x8000; // limit output to stereo
|
||||
int BASS_DEVICE_AUDIOTRACK = 0x20000; // use AudioTrack output
|
||||
int BASS_DEVICE_DSOUND = 0x40000; // use DirectSound output
|
||||
int BASS_DEVICE_SOFTWARE = 0x80000; // disable hardware/fastpath output
|
||||
|
||||
@Structure.FieldOrder({"name", "driver", "flags"})
|
||||
class BASS_DEVICEINFO extends Structure {
|
||||
public String name; // description
|
||||
public String driver; // driver
|
||||
public int flags;
|
||||
}
|
||||
|
||||
// BASS_DEVICEINFO flags
|
||||
int BASS_DEVICE_ENABLED = 1;
|
||||
int BASS_DEVICE_DEFAULT = 2;
|
||||
int BASS_DEVICE_INIT = 4;
|
||||
|
||||
@Structure.FieldOrder({"flags", "hwsize", "hwfree", "freesam", "free3d", "minrate", "maxrate", "eax", "minbuf", "dsver", "latency", "initflags", "speakers", "freq"})
|
||||
class BASS_INFO extends Structure{
|
||||
public int flags; // device capabilities (DSCAPS_xxx flags)
|
||||
public int hwsize; // unused
|
||||
public int hwfree; // unused
|
||||
public int freesam; // unused
|
||||
public int free3d; // unused
|
||||
public int minrate; // unused
|
||||
public int maxrate; // unused
|
||||
public int eax; // unused
|
||||
public int minbuf; // recommended minimum buffer length in ms
|
||||
public int dsver; // DirectSound version
|
||||
public int latency; // average delay (in ms) before start of playback
|
||||
public int initflags; // BASS_Init "flags" parameter
|
||||
public int speakers; // number of speakers available
|
||||
public int freq; // current output rate
|
||||
}
|
||||
|
||||
// Recording device info structure
|
||||
@Structure.FieldOrder({"flags", "formats", "inputs", "singlein", "freq"})
|
||||
class BASS_RECORDINFO extends Structure {
|
||||
public int flags; // device capabilities (DSCCAPS_xxx flags)
|
||||
public int formats; // supported standard formats (WAVE_FORMAT_xxx flags)
|
||||
public int inputs; // number of inputs
|
||||
public boolean singlein; // TRUE = only 1 input can be set at a time
|
||||
public int freq; // current input rate
|
||||
}
|
||||
|
||||
// Sample info structure
|
||||
@Structure.FieldOrder({"freq", "chans", "flags", "length", "max", "origres", "chans", "mingap", "mode3d", "mindist", "maxdist", "iangle", "oangle", "outvol", "vam", "priority"})
|
||||
class BASS_SAMPLE extends Structure {
|
||||
public int freq; // default playback rate
|
||||
public float volume; // default volume (0-1)
|
||||
public float pan; // default pan (-1=left, 0=middle, 1=right)
|
||||
public int flags; // BASS_SAMPLE_xxx flags
|
||||
public int length; // length (in bytes)
|
||||
public int max; // maximum simultaneous playbacks
|
||||
public int origres; // original resolution bits
|
||||
public int chans; // number of channels
|
||||
public int mingap; // minimum gap (ms) between creating channels
|
||||
public int mode3d; // BASS_3DMODE_xxx mode
|
||||
public float mindist; // minimum distance
|
||||
public float maxdist; // maximum distance
|
||||
public int iangle; // angle of inside projection cone
|
||||
public int oangle; // angle of outside projection cone
|
||||
public float outvol; // delta-volume outside the projection cone
|
||||
public int vam; // unused
|
||||
public int priority; // unused
|
||||
}
|
||||
|
||||
int BASS_SAMPLE_8BITS = 1; // 8 bit
|
||||
int BASS_SAMPLE_FLOAT = 256; // 32-bit floating-point
|
||||
int BASS_SAMPLE_MONO = 2; // mono
|
||||
int BASS_SAMPLE_LOOP = 4; // looped
|
||||
int BASS_SAMPLE_3D = 8; // 3D functionality
|
||||
int BASS_SAMPLE_SOFTWARE = 16; // unused
|
||||
int BASS_SAMPLE_MUTEMAX = 32; // mute at max distance (3D only)
|
||||
int BASS_SAMPLE_VAM = 64; // unused
|
||||
int BASS_SAMPLE_FX = 128; // unused
|
||||
int BASS_SAMPLE_OVER_VOL = 0x10000; // override lowest volume
|
||||
int BASS_SAMPLE_OVER_POS = 0x20000; // override longest playing
|
||||
int BASS_SAMPLE_OVER_DIST = 0x30000; // override furthest from listener (3D only)
|
||||
|
||||
int BASS_STREAM_PRESCAN = 0x20000; // scan file for accurate seeking and length
|
||||
int BASS_STREAM_AUTOFREE = 0x40000; // automatically free the stream when it stops/ends
|
||||
int BASS_STREAM_RESTRATE = 0x80000; // restrict the download rate of internet file streams
|
||||
int BASS_STREAM_BLOCK = 0x100000; // download/play internet file stream in small blocks
|
||||
int BASS_STREAM_DECODE = 0x200000; // don't play the stream, only decode (BASS_ChannelGetData)
|
||||
int BASS_STREAM_STATUS = 0x800000; // give server status info (HTTP/ICY tags) in DOWNLOADPROC
|
||||
|
||||
int BASS_MP3_IGNOREDELAY = 0x200; // ignore LAME/Xing/VBRI/iTunes delay & padding info
|
||||
int BASS_MP3_SETPOS = BASS_STREAM_PRESCAN;
|
||||
|
||||
int BASS_MUSIC_FLOAT = BASS_SAMPLE_FLOAT;
|
||||
int BASS_MUSIC_MONO = BASS_SAMPLE_MONO;
|
||||
int BASS_MUSIC_LOOP = BASS_SAMPLE_LOOP;
|
||||
int BASS_MUSIC_3D = BASS_SAMPLE_3D;
|
||||
int BASS_MUSIC_FX = BASS_SAMPLE_FX;
|
||||
int BASS_MUSIC_AUTOFREE = BASS_STREAM_AUTOFREE;
|
||||
int BASS_MUSIC_DECODE = BASS_STREAM_DECODE;
|
||||
int BASS_MUSIC_PRESCAN = BASS_STREAM_PRESCAN; // calculate playback length
|
||||
int BASS_MUSIC_CALCLEN = BASS_MUSIC_PRESCAN;
|
||||
int BASS_MUSIC_RAMP = 0x200; // normal ramping
|
||||
int BASS_MUSIC_RAMPS = 0x400; // sensitive ramping
|
||||
int BASS_MUSIC_SURROUND = 0x800; // surround sound
|
||||
int BASS_MUSIC_SURROUND2 = 0x1000; // surround sound (mode 2)
|
||||
int BASS_MUSIC_FT2PAN = 0x2000; // apply FastTracker 2 panning to XM files
|
||||
int BASS_MUSIC_FT2MOD = 0x2000; // play .MOD as FastTracker 2 does
|
||||
int BASS_MUSIC_PT1MOD = 0x4000; // play .MOD as ProTracker 1 does
|
||||
int BASS_MUSIC_NONINTER = 0x10000; // non-interpolated sample mixing
|
||||
int BASS_MUSIC_SINCINTER = 0x800000; // sinc interpolated sample mixing
|
||||
int BASS_MUSIC_POSRESET = 0x8000; // stop all notes when moving position
|
||||
int BASS_MUSIC_POSRESETEX = 0x400000; // stop all notes and reset bmp/etc when moving position
|
||||
int BASS_MUSIC_STOPBACK = 0x80000; // stop the music on a backwards jump effect
|
||||
int BASS_MUSIC_NOSAMPLE = 0x100000; // don't load the samples
|
||||
|
||||
// Speaker assignment flags
|
||||
int BASS_SPEAKER_FRONT = 0x1000000; // front speakers
|
||||
int BASS_SPEAKER_REAR = 0x2000000; // rear speakers
|
||||
int BASS_SPEAKER_CENLFE = 0x3000000; // center & LFE speakers (5.1)
|
||||
int BASS_SPEAKER_SIDE = 0x4000000; // side speakers (7.1)
|
||||
static int BASS_SPEAKER_N(int n) { return n<<24; } // n'th pair of speakers (max 15)
|
||||
int BASS_SPEAKER_LEFT = 0x10000000; // modifier: left
|
||||
int BASS_SPEAKER_RIGHT = 0x20000000; // modifier: right
|
||||
int BASS_SPEAKER_FRONTLEFT = BASS_SPEAKER_FRONT | BASS_SPEAKER_LEFT;
|
||||
int BASS_SPEAKER_FRONTRIGHT = BASS_SPEAKER_FRONT | BASS_SPEAKER_RIGHT;
|
||||
int BASS_SPEAKER_REARLEFT = BASS_SPEAKER_REAR | BASS_SPEAKER_LEFT;
|
||||
int BASS_SPEAKER_REARRIGHT = BASS_SPEAKER_REAR | BASS_SPEAKER_RIGHT;
|
||||
int BASS_SPEAKER_CENTER = BASS_SPEAKER_CENLFE | BASS_SPEAKER_LEFT;
|
||||
int BASS_SPEAKER_LFE = BASS_SPEAKER_CENLFE | BASS_SPEAKER_RIGHT;
|
||||
int BASS_SPEAKER_SIDELEFT = BASS_SPEAKER_SIDE | BASS_SPEAKER_LEFT;
|
||||
int BASS_SPEAKER_SIDERIGHT = BASS_SPEAKER_SIDE | BASS_SPEAKER_RIGHT;
|
||||
int BASS_SPEAKER_REAR2 = BASS_SPEAKER_SIDE;
|
||||
int BASS_SPEAKER_REAR2LEFT = BASS_SPEAKER_SIDELEFT;
|
||||
int BASS_SPEAKER_REAR2RIGHT = BASS_SPEAKER_SIDERIGHT;
|
||||
|
||||
int BASS_ASYNCFILE = 0x40000000; // read file asynchronously
|
||||
|
||||
int BASS_RECORD_PAUSE = 0x8000; // start recording paused
|
||||
|
||||
// Channel info structure
|
||||
@Structure.FieldOrder({"freq", "chans", "flags", "ctype", "origres", "plugin", "sample", "filename"})
|
||||
class BASS_CHANNELINFO extends Structure {
|
||||
public int freq; // default playback rate
|
||||
public int chans; // channels
|
||||
public int flags;
|
||||
public int ctype; // type of channel
|
||||
public int origres; // original resolution
|
||||
public int plugin;
|
||||
public int sample;
|
||||
public String filename;
|
||||
}
|
||||
|
||||
int BASS_ORIGRES_FLOAT = 0x10000;
|
||||
|
||||
// BASS_CHANNELINFO types
|
||||
int BASS_CTYPE_SAMPLE = 1;
|
||||
int BASS_CTYPE_RECORD = 2;
|
||||
int BASS_CTYPE_STREAM = 0x10000;
|
||||
int BASS_CTYPE_STREAM_VORBIS = 0x10002;
|
||||
int BASS_CTYPE_STREAM_OGG = 0x10002;
|
||||
int BASS_CTYPE_STREAM_MP1 = 0x10003;
|
||||
int BASS_CTYPE_STREAM_MP2 = 0x10004;
|
||||
int BASS_CTYPE_STREAM_MP3 = 0x10005;
|
||||
int BASS_CTYPE_STREAM_AIFF = 0x10006;
|
||||
int BASS_CTYPE_STREAM_CA = 0x10007;
|
||||
int BASS_CTYPE_STREAM_MF = 0x10008;
|
||||
int BASS_CTYPE_STREAM_AM = 0x10009;
|
||||
int BASS_CTYPE_STREAM_SAMPLE = 0x1000a;
|
||||
int BASS_CTYPE_STREAM_DUMMY = 0x18000;
|
||||
int BASS_CTYPE_STREAM_DEVICE = 0x18001;
|
||||
int BASS_CTYPE_STREAM_WAV = 0x40000; // WAVE flag (LOWORD=codec)
|
||||
int BASS_CTYPE_STREAM_WAV_PCM = 0x50001;
|
||||
int BASS_CTYPE_STREAM_WAV_FLOAT = 0x50003;
|
||||
int BASS_CTYPE_MUSIC_MOD = 0x20000;
|
||||
int BASS_CTYPE_MUSIC_MTM = 0x20001;
|
||||
int BASS_CTYPE_MUSIC_S3M = 0x20002;
|
||||
int BASS_CTYPE_MUSIC_XM = 0x20003;
|
||||
int BASS_CTYPE_MUSIC_IT = 0x20004;
|
||||
int BASS_CTYPE_MUSIC_MO3 = 0x00100; // MO3 flag
|
||||
|
||||
@Structure.FieldOrder({"ctype", "name", "exts"})
|
||||
class BASS_PLUGINFORM extends Structure {
|
||||
int ctype; // channel type
|
||||
String name; // format description
|
||||
String exts; // file extension filter (*.ext1;*.ext2;etc...)
|
||||
}
|
||||
|
||||
@Structure.FieldOrder({"version", "formatc", "formats"})
|
||||
class BASS_PLUGININFO extends Structure {
|
||||
int version; // version (same form as BASS_GetVersion)
|
||||
int formatc; // number of formats
|
||||
BASS_PLUGINFORM[] formats; // the array of formats
|
||||
}
|
||||
|
||||
// 3D vector (for 3D positions/velocities/orientations)
|
||||
class BASS_3DVECTOR {
|
||||
BASS_3DVECTOR() {}
|
||||
BASS_3DVECTOR(float _x, float _y, float _z) { x=_x; y=_y; z=_z; }
|
||||
float x; // +=right, -=left
|
||||
float y; // +=up, -=down
|
||||
float z; // +=front, -=behind
|
||||
}
|
||||
|
||||
// 3D channel modes
|
||||
int BASS_3DMODE_NORMAL = 0; // normal 3D processing
|
||||
int BASS_3DMODE_RELATIVE = 1; // position is relative to the listener
|
||||
int BASS_3DMODE_OFF = 2; // no 3D processing
|
||||
|
||||
// software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM)
|
||||
int BASS_3DALG_DEFAULT = 0;
|
||||
int BASS_3DALG_OFF = 1;
|
||||
int BASS_3DALG_FULL = 2;
|
||||
int BASS_3DALG_LIGHT = 3;
|
||||
|
||||
// BASS_SampleGetChannel flags
|
||||
int BASS_SAMCHAN_NEW = 1; // get a new playback channel
|
||||
int BASS_SAMCHAN_STREAM = 2; // create a stream
|
||||
|
||||
interface STREAMPROC extends Callback
|
||||
{
|
||||
int STREAMPROC(int handle, Pointer buffer, int length, Pointer user);
|
||||
/* User stream callback function.
|
||||
handle : The stream that needs writing
|
||||
buffer : Buffer to write the samples in
|
||||
length : Number of bytes to write
|
||||
user : The 'user' parameter value given when calling BASS_StreamCreate
|
||||
RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end
|
||||
the stream. */
|
||||
}
|
||||
|
||||
int BASS_STREAMPROC_END = 0x80000000; // end of user stream flag
|
||||
|
||||
// Special STREAMPROCs
|
||||
int STREAMPROC_DUMMY = 0; // "dummy" stream
|
||||
int STREAMPROC_PUSH = -1; // push stream
|
||||
int STREAMPROC_DEVICE = -2; // device mix stream
|
||||
int STREAMPROC_DEVICE_3D = -3; // device 3D mix stream
|
||||
|
||||
// BASS_StreamCreateFileUser file systems
|
||||
int STREAMFILE_NOBUFFER = 0;
|
||||
int STREAMFILE_BUFFER = 1;
|
||||
int STREAMFILE_BUFFERPUSH = 2;
|
||||
|
||||
interface BASS_FILEPROCS extends Callback
|
||||
{
|
||||
// User file stream callback functions
|
||||
void FILECLOSEPROC(Pointer user);
|
||||
long FILELENPROC(Pointer user) ;
|
||||
int FILEREADPROC(Pointer buffer, int length, Pointer user);
|
||||
boolean FILESEEKPROC(long offset, Pointer user);
|
||||
}
|
||||
|
||||
// BASS_StreamPutFileData options
|
||||
int BASS_FILEDATA_END = 0; // end & close the file
|
||||
|
||||
// BASS_StreamGetFilePosition modes
|
||||
int BASS_FILEPOS_CURRENT = 0;
|
||||
int BASS_FILEPOS_DECODE = BASS_FILEPOS_CURRENT;
|
||||
int BASS_FILEPOS_DOWNLOAD = 1;
|
||||
int BASS_FILEPOS_END = 2;
|
||||
int BASS_FILEPOS_START = 3;
|
||||
int BASS_FILEPOS_CONNECTED = 4;
|
||||
int BASS_FILEPOS_BUFFER = 5;
|
||||
int BASS_FILEPOS_SOCKET = 6;
|
||||
int BASS_FILEPOS_ASYNCBUF = 7;
|
||||
int BASS_FILEPOS_SIZE = 8;
|
||||
int BASS_FILEPOS_BUFFERING = 9;
|
||||
int BASS_FILEPOS_AVAILABLE = 10;
|
||||
|
||||
interface DOWNLOADPROC extends Callback
|
||||
{
|
||||
void DOWNLOADPROC(Pointer buffer, int length, Pointer user);
|
||||
/* Internet stream download callback function.
|
||||
buffer : Buffer containing the downloaded data... NULL=end of download
|
||||
length : Number of bytes in the buffer
|
||||
user : The 'user' parameter value given when calling BASS_StreamCreateURL */
|
||||
}
|
||||
|
||||
// BASS_ChannelSetSync types
|
||||
int BASS_SYNC_POS = 0;
|
||||
int BASS_SYNC_END = 2;
|
||||
int BASS_SYNC_META = 4;
|
||||
int BASS_SYNC_SLIDE = 5;
|
||||
int BASS_SYNC_STALL = 6;
|
||||
int BASS_SYNC_DOWNLOAD = 7;
|
||||
int BASS_SYNC_FREE = 8;
|
||||
int BASS_SYNC_SETPOS = 11;
|
||||
int BASS_SYNC_MUSICPOS = 10;
|
||||
int BASS_SYNC_MUSICINST = 1;
|
||||
int BASS_SYNC_MUSICFX = 3;
|
||||
int BASS_SYNC_OGG_CHANGE = 12;
|
||||
int BASS_SYNC_DEV_FAIL = 14;
|
||||
int BASS_SYNC_DEV_FORMAT = 15;
|
||||
int BASS_SYNC_THREAD = 0x20000000; // flag: call sync in other thread
|
||||
int BASS_SYNC_MIXTIME = 0x40000000; // flag: sync at mixtime, else at playtime
|
||||
int BASS_SYNC_ONETIME = 0x80000000; // flag: sync only once, else continuously
|
||||
|
||||
interface SYNCPROC extends Callback
|
||||
{
|
||||
void SYNCPROC(int handle, int channel, int data, Pointer user);
|
||||
/* Sync callback function.
|
||||
handle : The sync that has occured
|
||||
channel: Channel that the sync occured in
|
||||
data : Additional data associated with the sync's occurance
|
||||
user : The 'user' parameter given when calling BASS_ChannelSetSync */
|
||||
}
|
||||
|
||||
interface DSPPROC extends Callback
|
||||
{
|
||||
void DSPPROC(int handle, int channel, Pointer buffer, int length, Pointer user);
|
||||
/* DSP callback function.
|
||||
handle : The DSP handle
|
||||
channel: Channel that the DSP is being applied to
|
||||
buffer : Buffer to apply the DSP to
|
||||
length : Number of bytes in the buffer
|
||||
user : The 'user' parameter given when calling BASS_ChannelSetDSP */
|
||||
}
|
||||
|
||||
interface RECORDPROC extends Callback
|
||||
{
|
||||
boolean RECORDPROC(int handle, Pointer buffer, int length, Pointer user);
|
||||
/* Recording callback function.
|
||||
handle : The recording handle
|
||||
buffer : Buffer containing the recorded sample data
|
||||
length : Number of bytes
|
||||
user : The 'user' parameter value given when calling BASS_RecordStart
|
||||
RETURN : true = continue recording, false = stop */
|
||||
}
|
||||
|
||||
// BASS_ChannelIsActive return values
|
||||
int BASS_ACTIVE_STOPPED = 0;
|
||||
int BASS_ACTIVE_PLAYING =1;
|
||||
int BASS_ACTIVE_STALLED = 2;
|
||||
int BASS_ACTIVE_PAUSED = 3;
|
||||
int BASS_ACTIVE_PAUSED_DEVICE = 4;
|
||||
|
||||
// Channel attributes
|
||||
int BASS_ATTRIB_FREQ = 1;
|
||||
int BASS_ATTRIB_VOL = 2;
|
||||
int BASS_ATTRIB_PAN = 3;
|
||||
int BASS_ATTRIB_EAXMIX = 4;
|
||||
int BASS_ATTRIB_NOBUFFER = 5;
|
||||
int BASS_ATTRIB_VBR = 6;
|
||||
int BASS_ATTRIB_CPU = 7;
|
||||
int BASS_ATTRIB_SRC = 8;
|
||||
int BASS_ATTRIB_NET_RESUME = 9;
|
||||
int BASS_ATTRIB_SCANINFO = 10;
|
||||
int BASS_ATTRIB_NORAMP = 11;
|
||||
int BASS_ATTRIB_BITRATE = 12;
|
||||
int BASS_ATTRIB_BUFFER = 13;
|
||||
int BASS_ATTRIB_GRANULE = 14;
|
||||
int BASS_ATTRIB_USER = 15;
|
||||
int BASS_ATTRIB_TAIL = 16;
|
||||
int BASS_ATTRIB_PUSH_LIMIT = 17;
|
||||
int BASS_ATTRIB_DOWNLOADPROC = 18;
|
||||
int BASS_ATTRIB_VOLDSP = 19;
|
||||
int BASS_ATTRIB_VOLDSP_PRIORITY = 20;
|
||||
int BASS_ATTRIB_MUSIC_AMPLIFY = 0x100;
|
||||
int BASS_ATTRIB_MUSIC_PANSEP = 0x101;
|
||||
int BASS_ATTRIB_MUSIC_PSCALER = 0x102;
|
||||
int BASS_ATTRIB_MUSIC_BPM = 0x103;
|
||||
int BASS_ATTRIB_MUSIC_SPEED = 0x104;
|
||||
int BASS_ATTRIB_MUSIC_VOL_GLOBAL = 0x105;
|
||||
int BASS_ATTRIB_MUSIC_VOL_CHAN = 0x200; // + channel #
|
||||
int BASS_ATTRIB_MUSIC_VOL_INST = 0x300; // + instrument #
|
||||
|
||||
// BASS_ChannelSlideAttribute flags
|
||||
int BASS_SLIDE_LOG = 0x1000000;
|
||||
|
||||
// BASS_ChannelGetData flags
|
||||
int BASS_DATA_AVAILABLE = 0; // query how much data is buffered
|
||||
int BASS_DATA_NOREMOVE = 0x10000000; // flag: don't remove data from recording buffer
|
||||
int BASS_DATA_FIXED = 0x20000000; // unused
|
||||
int BASS_DATA_FLOAT = 0x40000000; // flag: return floating-point sample data
|
||||
int BASS_DATA_FFT256 = 0x80000000; // 256 sample FFT
|
||||
int BASS_DATA_FFT512 = 0x80000001; // 512 FFT
|
||||
int BASS_DATA_FFT1024 = 0x80000002; // 1024 FFT
|
||||
int BASS_DATA_FFT2048 = 0x80000003; // 2048 FFT
|
||||
int BASS_DATA_FFT4096 = 0x80000004; // 4096 FFT
|
||||
int BASS_DATA_FFT8192 = 0x80000005; // 8192 FFT
|
||||
int BASS_DATA_FFT16384 = 0x80000006; // 16384 FFT
|
||||
int BASS_DATA_FFT32768 = 0x80000007; // 32768 FFT
|
||||
int BASS_DATA_FFT_INDIVIDUAL = 0x10; // FFT flag: FFT for each channel, else all combined
|
||||
int BASS_DATA_FFT_NOWINDOW = 0x20; // FFT flag: no Hanning window
|
||||
int BASS_DATA_FFT_REMOVEDC = 0x40; // FFT flag: pre-remove DC bias
|
||||
int BASS_DATA_FFT_COMPLEX = 0x80; // FFT flag: return complex data
|
||||
int BASS_DATA_FFT_NYQUIST = 0x100; // FFT flag: return extra Nyquist value
|
||||
|
||||
// BASS_ChannelGetLevelEx flags
|
||||
int BASS_LEVEL_MONO = 1; // get mono level
|
||||
int BASS_LEVEL_STEREO = 2; // get stereo level
|
||||
int BASS_LEVEL_RMS = 4; // get RMS levels
|
||||
int BASS_LEVEL_VOLPAN = 8; // apply VOL/PAN attributes to the levels
|
||||
int BASS_LEVEL_NOREMOVE = 16; // don't remove data from recording buffer
|
||||
|
||||
// BASS_ChannelGetTags types : what's returned
|
||||
int BASS_TAG_ID3 = 0; // ID3v1 tags : TAG_ID3
|
||||
int BASS_TAG_ID3V2 = 1; // ID3v2 tags : ByteBuffer
|
||||
int BASS_TAG_OGG = 2; // OGG comments : String array
|
||||
int BASS_TAG_HTTP = 3; // HTTP headers : String array
|
||||
int BASS_TAG_ICY = 4; // ICY headers : String array
|
||||
int BASS_TAG_META = 5; // ICY metadata : String
|
||||
int BASS_TAG_APE = 6; // APE tags : String array
|
||||
int BASS_TAG_MP4 = 7; // MP4/iTunes metadata : String array
|
||||
int BASS_TAG_VENDOR = 9; // OGG encoder : String
|
||||
int BASS_TAG_LYRICS3 = 10; // Lyric3v2 tag : String
|
||||
int BASS_TAG_WAVEFORMAT = 14; // WAVE format : ByteBuffer containing WAVEFORMATEEX structure
|
||||
int BASS_TAG_AM_NAME = 16; // Android Media codec name : String
|
||||
int BASS_TAG_ID3V2_2 = 17; // ID3v2 tags (2nd block) : ByteBuffer
|
||||
int BASS_TAG_AM_MIME = 18; // Android Media MIME type : String
|
||||
int BASS_TAG_LOCATION = 19; // redirected URL : String
|
||||
int BASS_TAG_RIFF_INFO = 0x100; // RIFF "INFO" tags : String array
|
||||
int BASS_TAG_RIFF_BEXT = 0x101; // RIFF/BWF "bext" tags : TAG_BEXT
|
||||
int BASS_TAG_RIFF_CART = 0x102; // RIFF/BWF "cart" tags : TAG_CART
|
||||
int BASS_TAG_RIFF_DISP = 0x103; // RIFF "DISP" text tag : String
|
||||
int BASS_TAG_RIFF_CUE = 0x104; // RIFF "cue " chunk : TAG_CUE structure
|
||||
int BASS_TAG_RIFF_SMPL = 0x105; // RIFF "smpl" chunk : TAG_SMPL structure
|
||||
int BASS_TAG_APE_BINARY = 0x1000; // + index #, binary APE tag : TAG_APE_BINARY
|
||||
int BASS_TAG_MUSIC_NAME = 0x10000; // MOD music name : String
|
||||
int BASS_TAG_MUSIC_MESSAGE = 0x10001; // MOD message : String
|
||||
int BASS_TAG_MUSIC_ORDERS = 0x10002; // MOD order list : ByteBuffer
|
||||
int BASS_TAG_MUSIC_AUTH = 0x10003; // MOD author : UTF-8 string
|
||||
int BASS_TAG_MUSIC_INST = 0x10100; // + instrument #, MOD instrument name : String
|
||||
int BASS_TAG_MUSIC_CHAN = 0x10200; // + channel #, MOD channel name : String
|
||||
int BASS_TAG_MUSIC_SAMPLE = 0x10300; // + sample #, MOD sample name : String
|
||||
int BASS_TAG_BYTEBUFFER = 0x10000000; // flag: return a ByteBuffer instead of a String or TAG_ID3
|
||||
|
||||
// ID3v1 tag structure
|
||||
@Structure.FieldOrder({"id", "title", "artist", "album", "year", "comment", "genre", "track"})
|
||||
class TAG_ID3 extends Structure {
|
||||
String id;
|
||||
String title;
|
||||
String artist;
|
||||
String album;
|
||||
String year;
|
||||
String comment;
|
||||
byte genre;
|
||||
byte track;
|
||||
}
|
||||
|
||||
// Binary APE tag structure
|
||||
@Structure.FieldOrder({"key", "data", "length"})
|
||||
class TAG_APE_BINARY extends Structure {
|
||||
String key;
|
||||
Pointer data;
|
||||
int length;
|
||||
}
|
||||
|
||||
// BASS_ChannelGetLength/GetPosition/SetPosition modes
|
||||
int BASS_POS_BYTE = 0; // byte position
|
||||
int BASS_POS_MUSIC_ORDER = 1; // order.row position, MAKELONG(order,row)
|
||||
int BASS_POS_OGG = 3; // OGG bitstream number
|
||||
int BASS_POS_END = 0x10; // trimmed end position
|
||||
int BASS_POS_LOOP = 0x11; // loop start positiom
|
||||
int BASS_POS_FLUSH = 0x1000000; // flag: flush decoder/FX buffers
|
||||
int BASS_POS_RESET = 0x2000000; // flag: reset user file buffers
|
||||
int BASS_POS_RELATIVE = 0x4000000; // flag: seek relative to the current position
|
||||
int BASS_POS_INEXACT = 0x8000000; // flag: allow seeking to inexact position
|
||||
int BASS_POS_DECODE = 0x10000000; // flag: get the decoding (not playing) position
|
||||
int BASS_POS_DECODETO = 0x20000000; // flag: decode to the position instead of seeking
|
||||
int BASS_POS_SCAN = 0x40000000; // flag: scan to the position
|
||||
|
||||
// BASS_ChannelSetDevice/GetDevice option
|
||||
int BASS_NODEVICE = 0x20000;
|
||||
|
||||
// DX8 effect types, use with BASS_ChannelSetFX
|
||||
int BASS_FX_DX8_CHORUS = 0;
|
||||
int BASS_FX_DX8_COMPRESSOR = 1;
|
||||
int BASS_FX_DX8_DISTORTION = 2;
|
||||
int BASS_FX_DX8_ECHO = 3;
|
||||
int BASS_FX_DX8_FLANGER = 4;
|
||||
int BASS_FX_DX8_GARGLE = 5;
|
||||
int BASS_FX_DX8_I3DL2REVERB = 6;
|
||||
int BASS_FX_DX8_PARAMEQ = 7;
|
||||
int BASS_FX_DX8_REVERB = 8;
|
||||
int BASS_FX_VOLUME = 9;
|
||||
|
||||
@Structure.FieldOrder({"fWetDryMix", "fDepth", "fFeedback", "fFrequency", "lWaveform", "fDelay", "lPhase"})
|
||||
class BASS_DX8_CHORUS extends Structure {
|
||||
float fWetDryMix;
|
||||
float fDepth;
|
||||
float fFeedback;
|
||||
float fFrequency;
|
||||
int lWaveform; // 0=triangle, 1=sine
|
||||
float fDelay;
|
||||
int lPhase; // BASS_DX8_PHASE_xxx
|
||||
}
|
||||
|
||||
@Structure.FieldOrder({"fGain","fEdge","fPostEQCenterFrequency","fPostEQBandwidth","fPreLowpassCutoff"})
|
||||
class BASS_DX8_DISTORTION extends Structure {
|
||||
float fGain;
|
||||
float fEdge;
|
||||
float fPostEQCenterFrequency;
|
||||
float fPostEQBandwidth;
|
||||
float fPreLowpassCutoff;
|
||||
}
|
||||
|
||||
@Structure.FieldOrder({"fWetDryMix","fFeedback","fLeftDelay","fRightDelay","lPanDelay"})
|
||||
class BASS_DX8_ECHO extends Structure {
|
||||
float fWetDryMix;
|
||||
float fFeedback;
|
||||
float fLeftDelay;
|
||||
float fRightDelay;
|
||||
boolean lPanDelay;
|
||||
}
|
||||
|
||||
@Structure.FieldOrder({"fWetDryMix","fDepth","fFeedback","fFrequency","lWaveform","fDelay","lPhase"})
|
||||
class BASS_DX8_FLANGER extends Structure {
|
||||
float fWetDryMix;
|
||||
float fDepth;
|
||||
float fFeedback;
|
||||
float fFrequency;
|
||||
int lWaveform; // 0=triangle, 1=sine
|
||||
float fDelay;
|
||||
int lPhase; // BASS_DX8_PHASE_xxx
|
||||
}
|
||||
|
||||
@Structure.FieldOrder({"fCenter","fBandwidth","fGain"})
|
||||
class BASS_DX8_PARAMEQ extends Structure {
|
||||
float fCenter;
|
||||
float fBandwidth;
|
||||
float fGain;
|
||||
}
|
||||
|
||||
@Structure.FieldOrder({"fInGain","fReverbMix","fReverbTime","fHighFreqRTRatio"})
|
||||
class BASS_DX8_REVERB extends Structure {
|
||||
float fInGain;
|
||||
float fReverbMix;
|
||||
float fReverbTime;
|
||||
float fHighFreqRTRatio;
|
||||
}
|
||||
|
||||
int BASS_DX8_PHASE_NEG_180 = 0;
|
||||
int BASS_DX8_PHASE_NEG_90 = 1;
|
||||
int BASS_DX8_PHASE_ZERO = 2;
|
||||
int BASS_DX8_PHASE_90 = 3;
|
||||
int BASS_DX8_PHASE_180 = 4;
|
||||
|
||||
@Structure.FieldOrder({"fTarget","fCurrent","fTime","lCurve"})
|
||||
class BASS_FX_VOLUME_PARAM extends Structure {
|
||||
float fTarget;
|
||||
float fCurrent;
|
||||
float fTime;
|
||||
int lCurve;
|
||||
}
|
||||
|
||||
class FloatValue {
|
||||
public float value;
|
||||
}
|
||||
|
||||
boolean BASS_SetConfig(int option, int value);
|
||||
int BASS_GetConfig(int option);
|
||||
boolean BASS_SetConfigPtr(int option, Pointer value);
|
||||
Object BASS_GetConfigPtr(int option);
|
||||
int BASS_GetVersion();
|
||||
int BASS_ErrorGetCode();
|
||||
boolean BASS_GetDeviceInfo(int device, BASS_DEVICEINFO info);
|
||||
boolean BASS_Init(int device, int freq, int flags);
|
||||
boolean BASS_Free();
|
||||
boolean BASS_SetDevice(int device);
|
||||
int BASS_GetDevice();
|
||||
boolean BASS_GetInfo(BASS_INFO info);
|
||||
boolean BASS_Start();
|
||||
boolean BASS_Stop();
|
||||
boolean BASS_Pause();
|
||||
int BASS_IsStarted();
|
||||
boolean BASS_Update(int length);
|
||||
float BASS_GetCPU();
|
||||
boolean BASS_SetVolume(float volume);
|
||||
float BASS_GetVolume();
|
||||
|
||||
boolean BASS_Set3DFactors(float distf, float rollf, float doppf);
|
||||
boolean BASS_Get3DFactors(FloatValue distf, FloatValue rollf, FloatValue doppf);
|
||||
boolean BASS_Set3DPosition(BASS_3DVECTOR pos, BASS_3DVECTOR vel, BASS_3DVECTOR front, BASS_3DVECTOR top);
|
||||
boolean BASS_Get3DPosition(BASS_3DVECTOR pos, BASS_3DVECTOR vel, BASS_3DVECTOR front, BASS_3DVECTOR top);
|
||||
void BASS_Apply3D();
|
||||
|
||||
int BASS_PluginLoad(String file, int flags);
|
||||
boolean BASS_PluginFree(int handle);
|
||||
boolean BASS_PluginEnable(int handle, boolean enable);
|
||||
BASS_PLUGININFO BASS_PluginGetInfo(int handle);
|
||||
|
||||
int BASS_SampleLoad(String file, long offset, int length, int max, int flags);
|
||||
int BASS_SampleLoad(Pointer file, long offset, int length, int max, int flags);
|
||||
int BASS_SampleCreate(int length, int freq, int chans, int max, int flags);
|
||||
boolean BASS_SampleFree(int handle);
|
||||
boolean BASS_SampleSetData(int handle, Pointer buffer);
|
||||
boolean BASS_SampleGetData(int handle, Pointer buffer);
|
||||
boolean BASS_SampleGetInfo(int handle, BASS_SAMPLE info);
|
||||
boolean BASS_SampleSetInfo(int handle, BASS_SAMPLE info);
|
||||
int BASS_SampleGetChannel(int handle, boolean onlynew);
|
||||
int BASS_SampleGetChannels(int handle, int[] channels);
|
||||
boolean BASS_SampleStop(int handle);
|
||||
|
||||
int BASS_StreamCreate(int freq, int chans, int flags, STREAMPROC proc, Pointer user);
|
||||
int BASS_StreamCreateFile(boolean mem, String file, long offset, long length, int flags);
|
||||
int BASS_StreamCreateFile(Pointer file, long offset, long length, int flags);
|
||||
int BASS_StreamCreateURL(String url, int offset, int flags, DOWNLOADPROC proc, Pointer user);
|
||||
int BASS_StreamCreateFileUser(int system, int flags, BASS_FILEPROCS procs, Pointer user);
|
||||
boolean BASS_StreamFree(int handle);
|
||||
long BASS_StreamGetFilePosition(int handle, int mode);
|
||||
int BASS_StreamPutData(int handle, Pointer buffer, int length);
|
||||
int BASS_StreamPutFileData(int handle, Pointer buffer, int length);
|
||||
|
||||
int BASS_MusicLoad(String file, long offset, int length, int flags, int freq);
|
||||
int BASS_MusicLoad(Pointer file, long offset, int length, int flags, int freq);
|
||||
boolean BASS_MusicFree(int handle);
|
||||
|
||||
boolean BASS_RecordGetDeviceInfo(int device, BASS_DEVICEINFO info);
|
||||
boolean BASS_RecordInit(int device);
|
||||
boolean BASS_RecordFree();
|
||||
boolean BASS_RecordSetDevice(int device);
|
||||
int BASS_RecordGetDevice();
|
||||
boolean BASS_RecordGetInfo(BASS_RECORDINFO info);
|
||||
String BASS_RecordGetInputName(int input);
|
||||
boolean BASS_RecordSetInput(int input, int flags, float volume);
|
||||
int BASS_RecordGetInput(int input, FloatValue volume);
|
||||
int BASS_RecordStart(int freq, int chans, int flags, RECORDPROC proc, Pointer user);
|
||||
|
||||
double BASS_ChannelBytes2Seconds(int handle, long pos);
|
||||
long BASS_ChannelSeconds2Bytes(int handle, double pos);
|
||||
int BASS_ChannelGetDevice(int handle);
|
||||
boolean BASS_ChannelSetDevice(int handle, int device);
|
||||
int BASS_ChannelIsActive(int handle);
|
||||
boolean BASS_ChannelGetInfo(int handle, BASS_CHANNELINFO info);
|
||||
Object BASS_ChannelGetTags(int handle, int tags);
|
||||
long BASS_ChannelFlags(int handle, int flags, int mask);
|
||||
boolean BASS_ChannelLock(int handle, boolean lock);
|
||||
boolean BASS_ChannelFree(int handle);
|
||||
boolean BASS_ChannelPlay(int handle, boolean restart);
|
||||
boolean BASS_ChannelStart(int handle);
|
||||
boolean BASS_ChannelStop(int handle);
|
||||
boolean BASS_ChannelPause(int handle);
|
||||
boolean BASS_ChannelUpdate(int handle, int length);
|
||||
boolean BASS_ChannelSetAttribute(int handle, int attrib, float value);
|
||||
boolean BASS_ChannelGetAttribute(int handle, int attrib, FloatValue value);
|
||||
boolean BASS_ChannelSlideAttribute(int handle, int attrib, float value, int time);
|
||||
boolean BASS_ChannelIsSliding(int handle, int attrib);
|
||||
boolean BASS_ChannelSetAttributeEx(int handle, int attrib, Pointer value, int size);
|
||||
boolean BASS_ChannelSetAttributeDOWNLOADPROC(int handle, DOWNLOADPROC proc, Pointer user);
|
||||
int BASS_ChannelGetAttributeEx(int handle, int attrib, Pointer value, int size);
|
||||
boolean BASS_ChannelSet3DAttributes(int handle, int mode, float min, float max, int iangle, int oangle, float outvol);
|
||||
boolean BASS_ChannelGet3DAttributes(int handle, Integer mode, FloatValue min, FloatValue max, Integer iangle, Integer oangle, FloatValue outvol);
|
||||
boolean BASS_ChannelSet3DPosition(int handle, BASS_3DVECTOR pos, BASS_3DVECTOR orient, BASS_3DVECTOR vel);
|
||||
boolean BASS_ChannelGet3DPosition(int handle, BASS_3DVECTOR pos, BASS_3DVECTOR orient, BASS_3DVECTOR vel);
|
||||
long BASS_ChannelGetLength(int handle, int mode);
|
||||
boolean BASS_ChannelSetPosition(int handle, long pos, int mode);
|
||||
long BASS_ChannelGetPosition(int handle, int mode);
|
||||
int BASS_ChannelGetLevel(int handle);
|
||||
boolean BASS_ChannelGetLevelEx(int handle, float[] levels, float length, int flags);
|
||||
int BASS_ChannelGetData(int handle, Pointer buffer, int length);
|
||||
int BASS_ChannelSetSync(int handle, int type, long param, SYNCPROC proc, Pointer user);
|
||||
boolean BASS_ChannelRemoveSync(int handle, int sync);
|
||||
boolean BASS_ChannelSetLink(int handle, int chan);
|
||||
boolean BASS_ChannelRemoveLink(int handle, int chan);
|
||||
int BASS_ChannelSetDSP(int handle, DSPPROC proc, Pointer user, int priority);
|
||||
boolean BASS_ChannelRemoveDSP(int handle, int dsp);
|
||||
int BASS_ChannelSetFX(int handle, int type, int priority);
|
||||
boolean BASS_ChannelRemoveFX(int handle, int fx);
|
||||
|
||||
boolean BASS_FXSetParameters(int handle, Object params);
|
||||
boolean BASS_FXGetParameters(int handle, Object params);
|
||||
boolean BASS_FXSetPriority(int handle, int priority);
|
||||
boolean BASS_FXReset(int handle);
|
||||
// gak bisa
|
||||
int BASS_StreamCreate(int freq, int chans, int flags, int proc, Pointer user);
|
||||
|
||||
|
||||
|
||||
}
|
||||
8
src/main/java/Audio/PlaybackEvent.java
Normal file
8
src/main/java/Audio/PlaybackEvent.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package Audio;
|
||||
|
||||
public interface PlaybackEvent {
|
||||
void onPlaybackStart(AudioFileProperties prop);
|
||||
void onPlaybackFinished(AudioFileProperties prop);
|
||||
void onPlaybackFailure(AudioFileProperties prop, String reason);
|
||||
void onPlaybackLooped(AudioFileProperties prop);
|
||||
}
|
||||
122
src/main/java/Camera/GrabbingTask.java
Normal file
122
src/main/java/Camera/GrabbingTask.java
Normal file
@@ -0,0 +1,122 @@
|
||||
package Camera;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import Other.SomeCodes;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.FrameGrabber;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
public class GrabbingTask implements Runnable {
|
||||
@Setter private Consumer<String> onMessageUpdate;
|
||||
@Setter private Consumer<Mat> onMatUpdate;
|
||||
@Setter private Consumer<Frame> onFrameUpdate;
|
||||
@Setter private Consumer<String> onBase64Update;
|
||||
@Setter private Consumer<String> onStreamingStatusUpdate;
|
||||
|
||||
private final AtomicBoolean isGrabbing;
|
||||
private final FrameGrabber grabber;
|
||||
@Getter private final int lowquality_width = 640;
|
||||
@Getter private final int lowquality_height = 360;
|
||||
@Getter @Setter private boolean HQ = false;
|
||||
@Getter private int streaming_width = 0;
|
||||
@Getter private int streaming_height = 0;
|
||||
@Getter private int streaming_fps = 0;
|
||||
AtomicBoolean streamingstatuschanged = new AtomicBoolean(false);
|
||||
|
||||
private void updateMessage(String message) {
|
||||
if (onMessageUpdate != null) {
|
||||
onMessageUpdate.accept(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMat(Mat value) {
|
||||
if (onMatUpdate != null) {
|
||||
onMatUpdate.accept(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBase64(String base64) {
|
||||
if (onBase64Update != null) {
|
||||
onBase64Update.accept(base64);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFrame(Frame frame) {
|
||||
if (onFrameUpdate != null) {
|
||||
onFrameUpdate.accept(frame);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStreamingStatus(String status) {
|
||||
if (onStreamingStatusUpdate != null) {
|
||||
onStreamingStatusUpdate.accept(status);
|
||||
}
|
||||
}
|
||||
|
||||
public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber) {
|
||||
this.isGrabbing = isGrabbing;
|
||||
this.grabber = grabber;
|
||||
}
|
||||
|
||||
public String GetStreamingStatus(){
|
||||
return "Streaming at " + streaming_width + "x" + streaming_height + " " + streaming_fps + "fps";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
isGrabbing.set(true);
|
||||
AtomicInteger framecount = new AtomicInteger(0);
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (streaming_fps != framecount.get()) {
|
||||
streaming_fps = framecount.get();
|
||||
streamingstatuschanged.set(true);
|
||||
}
|
||||
framecount.set(0);
|
||||
if (streamingstatuschanged.get()) {
|
||||
updateStreamingStatus(GetStreamingStatus());
|
||||
streamingstatuschanged.set(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
Timer timer = new Timer();
|
||||
timer.scheduleAtFixedRate(task, 1000, 1000);
|
||||
while (isGrabbing.get()) {
|
||||
try {
|
||||
//Thread.sleep(100); // 10 fps
|
||||
Frame fr =grabber.grab();
|
||||
if (fr!=null){
|
||||
if (!HQ) fr = SomeCodes.ResizeFrame(fr, lowquality_width, lowquality_height);
|
||||
updateFrame(fr);
|
||||
updateBase64(SomeCodes.BufferedImageToBase64(SomeCodes.FrameToBufferedImage(fr)));
|
||||
Mat mat = SomeCodes.matConverter.convert(fr);
|
||||
updateMat(mat);
|
||||
if (streaming_width != fr.imageWidth) {
|
||||
streaming_width = fr.imageWidth;
|
||||
streamingstatuschanged.set(true);
|
||||
}
|
||||
if (streaming_height != fr.imageHeight) {
|
||||
streaming_height = fr.imageHeight;
|
||||
streamingstatuschanged.set(true);
|
||||
}
|
||||
framecount.incrementAndGet();
|
||||
|
||||
} else updateMessage("Grabber returned null frame");
|
||||
} catch (Exception e) {
|
||||
updateMessage("Error grabbing frame: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
117
src/main/java/Camera/PanTiltController.java
Normal file
117
src/main/java/Camera/PanTiltController.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package Camera;
|
||||
|
||||
import com.fazecast.jSerialComm.SerialPort;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
/**
|
||||
* Pan Tilt Controller
|
||||
* Using PelcoD protocol
|
||||
* Source : https://www.commfront.com/pages/pelco-d-protocol-tutorial
|
||||
*/
|
||||
public class PanTiltController {
|
||||
private final SerialPort serialPort;
|
||||
private final byte cameraid;
|
||||
/**
|
||||
* Open Pan Tilt Controller
|
||||
* @param portname serial port name used
|
||||
* @param baudrate baudrate used
|
||||
*/
|
||||
public PanTiltController(String portname, int baudrate, int cameraid){
|
||||
serialPort = SerialPort.getCommPort(portname);
|
||||
serialPort.setBaudRate(baudrate);
|
||||
this.cameraid = (byte)cameraid;
|
||||
if (serialPort.openPort()){
|
||||
Logger.info("Serial Port {} opened successfully at {}", portname, baudrate);
|
||||
} else {
|
||||
Logger.info("Failed to open Serial Port {} at {}", portname, baudrate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Pan Tilt Controller
|
||||
*/
|
||||
public void Close(){
|
||||
serialPort.closePort();
|
||||
Logger.info("Serial Port closed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop Pan Tilt Movement
|
||||
*/
|
||||
public void StopMovement(){
|
||||
byte[] command = new byte[]{0, cameraid, 0, 0, 0, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pan Left
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void PanLeft(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 4, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pan Right
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void PanRight(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 2, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tilt Up
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void TiltUp(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 8, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tilt Down
|
||||
* @param speed speed of movement, 0-63
|
||||
*/
|
||||
public void TiltDown(byte speed){
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
|
||||
byte[] command = new byte[]{0, cameraid, 0, 16, speed, 0, 0};
|
||||
command[6] = Checksum(command); // add checksum
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
serialPort.writeBytes(command, command.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum of bytes, then modulo by 256
|
||||
* @param data data to be summed
|
||||
* @return checksum
|
||||
*/
|
||||
private byte Checksum(byte[] data){
|
||||
int sum = 0;
|
||||
for (byte b : data){
|
||||
sum += b;
|
||||
}
|
||||
|
||||
return (byte)(sum % 256);
|
||||
}
|
||||
}
|
||||
11
src/main/java/Camera/RtspEvent.java
Normal file
11
src/main/java/Camera/RtspEvent.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package Camera;
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
public interface RtspEvent {
|
||||
void onMatReceived(Mat mat);
|
||||
void onFrameReceived(Frame frame);
|
||||
void onBase64Received(String base64);
|
||||
void onStreamingStatusReceived(String status);
|
||||
}
|
||||
120
src/main/java/Camera/RtspGrabber.java
Normal file
120
src/main/java/Camera/RtspGrabber.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package Camera;
|
||||
import lombok.Getter;
|
||||
import org.bytedeco.ffmpeg.global.avutil;
|
||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RtspGrabber {
|
||||
private final String rtspUrl;
|
||||
private FFmpegFrameGrabber grabber;
|
||||
private final AtomicBoolean isGrabbing = new AtomicBoolean(false);
|
||||
private @Getter Frame lastFrame = null;
|
||||
private @Getter String lastBase64 = null;
|
||||
private @Getter Mat lastMat = null;
|
||||
private GrabbingTask grabbingTask = null;
|
||||
|
||||
public RtspGrabber(String ip, int port, String username, String password, String path) {
|
||||
rtspUrl = "rtsp://" + username + ":" + password + "@" + ip + ":" + port + path;
|
||||
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
||||
|
||||
}
|
||||
|
||||
public RtspGrabber(String ip, String path) {
|
||||
this.rtspUrl = "rtsp://" + ip + path;
|
||||
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start grabbing frames from rtsp
|
||||
* @param useTcp Use tcp instead of udp
|
||||
* @param event Event to be called when frame is received
|
||||
*/
|
||||
public void Start(boolean useTcp, final int width, final int height, RtspEvent event){
|
||||
|
||||
try{
|
||||
grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
|
||||
if (useTcp) grabber.setOption("rtsp_transport", "tcp");
|
||||
//grabber.setImageWidth(width);
|
||||
//grabber.setImageHeight(height);
|
||||
|
||||
grabber.setPixelFormat(avutil.AV_PIX_FMT_BGR24);
|
||||
grabber.start();
|
||||
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
|
||||
|
||||
|
||||
|
||||
Logger.info("Grabber started");
|
||||
GrabbingTask tt = new GrabbingTask(isGrabbing, grabber);
|
||||
tt.setOnMessageUpdate(Logger::info);
|
||||
tt.setOnMatUpdate(value -> {
|
||||
// Kalau butuh Mat untuk diproses
|
||||
lastMat = value;
|
||||
if (event!=null) event.onMatReceived(value);
|
||||
});
|
||||
tt.setOnFrameUpdate(value -> {
|
||||
// Kalau butuh Frame untuk ditampilkan
|
||||
lastFrame = value;
|
||||
|
||||
if (event!=null) event.onFrameReceived(value);
|
||||
});
|
||||
tt.setOnBase64Update(value -> {
|
||||
// Kalau butuh Base64 untuk dikirim ke Websocket
|
||||
lastBase64 = value;
|
||||
if (event!=null) event.onBase64Received(value);
|
||||
});
|
||||
tt.setOnStreamingStatusUpdate(value -> {
|
||||
// Kalau butuh status streaming
|
||||
if (event!=null) event.onStreamingStatusReceived(value);
|
||||
});
|
||||
|
||||
new Thread(tt).start();
|
||||
grabbingTask = tt;
|
||||
|
||||
} catch (Exception e){
|
||||
Logger.error("Error starting grabber: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop grabbing frames
|
||||
*/
|
||||
public void Stop(){
|
||||
if (grabber!=null) {
|
||||
try{
|
||||
isGrabbing.set(false);
|
||||
grabber.stop();
|
||||
Logger.info("Grabber stopped");
|
||||
} catch (Exception e){
|
||||
Logger.error("Error stopping grabber: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if grabber is grabbing
|
||||
* @return True if grabbing
|
||||
*/
|
||||
public boolean IsGrabbing(){
|
||||
return isGrabbing.get();
|
||||
}
|
||||
|
||||
public void ChangeVideoQuality(boolean HQ){
|
||||
if (IsGrabbing()){
|
||||
if (grabbingTask!=null){
|
||||
grabbingTask.setHQ(HQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String GetStreamingStatus(){
|
||||
if (grabbingTask!=null){
|
||||
return grabbingTask.GetStreamingStatus();
|
||||
}
|
||||
return "No Status";
|
||||
}
|
||||
}
|
||||
348
src/main/java/Camera/VapixProtocol.java
Normal file
348
src/main/java/Camera/VapixProtocol.java
Normal file
@@ -0,0 +1,348 @@
|
||||
package Camera;
|
||||
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.awt.*;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static Other.SomeCodes.ValidInteger;
|
||||
import static Other.SomeCodes.ValidString;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class VapixProtocol {
|
||||
|
||||
private final String url;
|
||||
private final HttpClient client;
|
||||
private String parameters;
|
||||
|
||||
private String ProductNumberValue = "";
|
||||
private String SerialNumberValue = "";
|
||||
private int CameraIDValue = 0;
|
||||
private int MaxZoomValue = 0;
|
||||
private int MinZoomValue = 0;
|
||||
private boolean PTZEnabledValue = false;
|
||||
private String[] ImageResolutions = new String[0];
|
||||
private String[] ImageFormats = new String[0];
|
||||
private int CurrentZoomValue = 0;
|
||||
|
||||
/**
|
||||
* Create a new VapixProtocol object
|
||||
* @param ip The IP address of the camera
|
||||
* @param port The HTTP port of the camera
|
||||
* @param username The username to access the camera (optional)
|
||||
* @param password The password to access the camera (optional)
|
||||
*/
|
||||
public VapixProtocol(String ip, int port, String username, String password) {
|
||||
url = "http://" + ip + ":" + port+"/axis-cgi/";
|
||||
String auth = username + ":" + password;
|
||||
//encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
|
||||
client = HttpClient.newHttpClient();
|
||||
GetParameters(null);
|
||||
if (ValidString(parameters)){
|
||||
Pattern ProductNumber = Pattern.compile(".*ProdNbr=(.*)");
|
||||
Matcher m1 = ProductNumber.matcher(parameters);
|
||||
if (m1.find()) ProductNumberValue = m1.group(1);
|
||||
Pattern SerialNumber = Pattern.compile(".*SerialNumber=(.*)");
|
||||
Matcher m2 = SerialNumber.matcher(parameters);
|
||||
if (m2.find()) SerialNumberValue = m2.group(1);
|
||||
Pattern PTZCamId = Pattern.compile(".*CamId=(.*)");
|
||||
Matcher m3 = PTZCamId.matcher(parameters);
|
||||
if (m3.find()) {
|
||||
String value = m3.group(1);
|
||||
if (ValidInteger(value)) CameraIDValue = Integer.parseInt(value);
|
||||
}
|
||||
Pattern PTZMaxZoom = Pattern.compile(".*MaxZoom=(.*)");
|
||||
Matcher m4 = PTZMaxZoom.matcher(parameters);
|
||||
if (m4.find()) {
|
||||
String value = m4.group(1);
|
||||
if (ValidInteger(value)) MaxZoomValue = Integer.parseInt(value);
|
||||
}
|
||||
Pattern PTZMinZoom = Pattern.compile(".*MinZoom=(.*)");
|
||||
Matcher m5 = PTZMinZoom.matcher(parameters);
|
||||
if (m5.find()) {
|
||||
String value = m5.group(1);
|
||||
if (ValidInteger(value)) MinZoomValue = Integer.parseInt(value);
|
||||
}
|
||||
Pattern PTZEnabled = Pattern.compile(".*PTZ.PTZ=(.*)");
|
||||
Matcher m6 = PTZEnabled.matcher(parameters);
|
||||
if (m6.find()) PTZEnabledValue = m6.group(1).contains("yes");
|
||||
Pattern Resolution = Pattern.compile(".*Image.Resolution=(.*)");
|
||||
Matcher m7 = Resolution.matcher(parameters);
|
||||
if (m7.find()) {
|
||||
String value = m7.group(1);
|
||||
if (ValidString(value)) ImageResolutions = value.split(",");
|
||||
//Logger.info("Resolution: "+value);
|
||||
}
|
||||
Pattern Format = Pattern.compile(".*Image.Format=(.*)");
|
||||
Matcher m8 = Format.matcher(parameters);
|
||||
if (m8.find()) {
|
||||
String value = m8.group(1);
|
||||
if (ValidString(value)) ImageFormats = value.split(",");
|
||||
//Logger.info("Format: "+value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private void GetParameters(String group){
|
||||
String command = url+"param.cgi?action=list";
|
||||
if (ValidString(group)) command+="&group="+group;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
parameters = "";
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
parameters = response.body();
|
||||
} else Logger.info("Error getting parameters: "+response.statusCode());
|
||||
} catch (Exception e){
|
||||
Logger.error("Error getting parameters: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Product Number of the camera
|
||||
* @return Product Number, or empty string if not available
|
||||
*/
|
||||
public String GetProductNumber(){
|
||||
return ProductNumberValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Serial Number of the camera
|
||||
* @return Serial Number, or empty string if not available
|
||||
*/
|
||||
public String GetSerialNumber(){
|
||||
return SerialNumberValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get PTZ Camera ID
|
||||
* @return Camera ID
|
||||
*/
|
||||
public int GetPTZCameraID(){
|
||||
return CameraIDValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Maximum Zoom Value
|
||||
* @return Maximum Zoom Value
|
||||
*/
|
||||
public int GetPTZMaxZoom(){
|
||||
return MaxZoomValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Minimum Zoom Value
|
||||
* @return Minimum Zoom Value
|
||||
*/
|
||||
public int GetPTZMinZoom(){
|
||||
return MinZoomValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if PTZ Control enabled for this camera
|
||||
* @return true if PTZ Control enabled, false otherwise
|
||||
*/
|
||||
public boolean PTZEnabled() {
|
||||
return PTZEnabledValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Available Image Resolutions
|
||||
* @return array of String, in format "widthxheight"
|
||||
*/
|
||||
public String[] GetImageResolutions(){
|
||||
return ImageResolutions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Available Image Formats
|
||||
* @return array of String, example "jpeg","mjpeg","h264","bitmap"
|
||||
*/
|
||||
public String[] GetImageFormats(){
|
||||
return ImageFormats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close VapiX Protocol
|
||||
*/
|
||||
public void Close(){
|
||||
if (client!=null) client.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom In / Out
|
||||
* @param cameraid Camera ID, get it from GetPTZCameraID()
|
||||
* @param zoom Zoom value, value between GetPTZMinZoom and GetPTZMaxZoom()
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
public boolean Zoom(int cameraid, int zoom){
|
||||
if (zoom < MinZoomValue) zoom = MinZoomValue;
|
||||
if (zoom > MaxZoomValue) zoom = MaxZoomValue;
|
||||
String command = url+"com/ptz.cgi?zoom="+zoom+"&camera="+cameraid;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
Logger.info("Zoom: "+response.body());
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error zooming: "+e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current Zoom Value
|
||||
* @return Current Zoom Value
|
||||
*/
|
||||
public int GetCurrentZoomValue(){
|
||||
update_ptz_query_position();
|
||||
return CurrentZoomValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current Image Resolution
|
||||
* @param cameraid Camera ID, get it from GetPTZCameraID()
|
||||
* @return array of int, [0] = width, [1] = height
|
||||
*/
|
||||
public int[] GetCurrentResolution(int cameraid){
|
||||
int[] result = new int[]{0,0};
|
||||
String command = url+"imagesize.cgi?camera="+cameraid;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
String values = response.body();
|
||||
//Something like this:
|
||||
//image width = 1920
|
||||
//image height = 1080
|
||||
for (String s : values.split("\n")) {
|
||||
String[] parts = s.split("=");
|
||||
if (parts.length==2){
|
||||
String part0 = parts[0].trim();
|
||||
String part1 = parts[1].trim();
|
||||
if (part0.contains("width")){
|
||||
if (ValidInteger(part1)) result[0] = Integer.parseInt(part1);
|
||||
}
|
||||
if (part0.contains("height")) {
|
||||
if (ValidInteger(part1)) result[1] = Integer.parseInt(part1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error getting resolution: "+e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Image Resolution
|
||||
* @param cameraid Camera ID, get it from GetPTZCameraID()
|
||||
* @param width Width of the image
|
||||
* @param height Height of the image
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
public boolean SetResolution(int cameraid, int width, int height){
|
||||
String resolution = width+"x"+height;
|
||||
boolean supported = false;
|
||||
for(String r: ImageResolutions){
|
||||
if (r.equals(resolution)){
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (supported){
|
||||
String command = url+"imagesize.cgi?camera="+cameraid+"&resolution="+resolution;
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
|
||||
Logger.info("Resolution set: "+response.body());
|
||||
String values = response.body();
|
||||
//Something like this:
|
||||
//image width = 1920
|
||||
//image height = 1080
|
||||
boolean width_ok = false;
|
||||
boolean height_ok = false;
|
||||
for (String s : values.split("\n")) {
|
||||
String[] parts = s.split("=");
|
||||
if (parts.length==2){
|
||||
String part0 = parts[0].trim();
|
||||
String part1 = parts[1].trim();
|
||||
if (part0.contains("width")){
|
||||
if (ValidInteger(part1)) {
|
||||
if (Integer.parseInt(part1)==width)
|
||||
width_ok = true;
|
||||
else Logger.error("Width failed, target: "+width+" actual: "+part1);
|
||||
}
|
||||
}
|
||||
if (part0.contains("height")) {
|
||||
if (ValidInteger(part1)) {
|
||||
if (Integer.parseInt(part1)==height)
|
||||
height_ok = true;
|
||||
else Logger.error("Height failed, target: "+height+" actual: "+part1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return width_ok && height_ok;
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error setting resolution: "+e.getMessage());
|
||||
}
|
||||
} else Logger.info("Resolution not supported: "+resolution);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void update_ptz_query_position(){
|
||||
String command = url+"com/ptz.cgi?query=position";
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(command))
|
||||
.build();
|
||||
try{
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
String values = response.body();
|
||||
|
||||
//Something like this:
|
||||
//pan=0.0000
|
||||
//tilt=0.0000
|
||||
//zoom=1
|
||||
//iris=5000
|
||||
//focus=9574
|
||||
//brightness=5000
|
||||
//autofocus=on
|
||||
//autoiris=off
|
||||
for (String s : values.split("\n")) {
|
||||
String[] parts = s.split("=");
|
||||
if (parts.length==2){
|
||||
if (parts[0].equals("zoom")) CurrentZoomValue = Integer.parseInt(parts[1].trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error getting PTZ position: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
245
src/main/java/Other/SomeCodes.java
Normal file
245
src/main/java/Other/SomeCodes.java
Normal file
@@ -0,0 +1,245 @@
|
||||
package Other;
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.Java2DFrameConverter;
|
||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||
import org.bytedeco.opencv.global.opencv_core;
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.Size;
|
||||
import org.bytedeco.opencv.opencv_core.UMat;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.file.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Properties;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class SomeCodes {
|
||||
public final static String currentDirectory = System.getProperty("user.dir");
|
||||
public final static Path audioPath = Path.of(currentDirectory, "audiofiles");
|
||||
private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
public static final OpenCVFrameConverter.ToMat matConverter = new OpenCVFrameConverter.ToMat();
|
||||
public static final Java2DFrameConverter frameConverter = new Java2DFrameConverter();
|
||||
public static final Path logsPath = Path.of(currentDirectory, "logs");
|
||||
public static final boolean haveOpenCL = opencv_core.haveOpenCL();
|
||||
public static boolean useOpenCL;
|
||||
|
||||
|
||||
public static String[] GetAudioFiles(){
|
||||
try{
|
||||
return Files.list(audioPath).map(f -> f.getFileName().toString()).toArray(String[]::new);
|
||||
} catch (Exception e){
|
||||
Logger.error("Error getting audio files: "+e.getMessage());
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public static String LocalDateTimeToString(LocalDateTime x){
|
||||
return x.format(dtf);
|
||||
}
|
||||
|
||||
public static String ExtractResource(String filename, String targetdirectory){
|
||||
try {
|
||||
File destination = new File(targetdirectory, filename);
|
||||
if (destination.exists()) {
|
||||
Logger.info("Resource File already exists: " + filename);
|
||||
return destination.getAbsolutePath();
|
||||
}
|
||||
|
||||
InputStream is = SomeCodes.class.getResourceAsStream(filename);
|
||||
if (is!=null){
|
||||
Files.copy(is, destination.toPath());
|
||||
Logger.info("Resource File extracted: "+filename);
|
||||
return destination.getAbsolutePath();
|
||||
} else {
|
||||
Logger.error("Resource File not found: "+filename);
|
||||
}
|
||||
|
||||
} catch (Exception e){
|
||||
Logger.error("Error extracting resource: "+filename+", Message : "+e.getMessage());
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean ValidDirectory(String path){
|
||||
if (ValidString(path)){
|
||||
File ff = new File(path);
|
||||
return ff.isDirectory();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ValidFile(String filename){
|
||||
if (ValidString(filename)){
|
||||
File ff = new File(filename);
|
||||
return ff.isFile();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ValidString(String x){
|
||||
if (x!=null){
|
||||
return !x.isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static byte GetPanTiltSpeed(String data, byte defaultspeed){
|
||||
if (ValidInteger(data)){
|
||||
int speed = Integer.parseInt(data);
|
||||
if (speed<0) speed = 0;
|
||||
if (speed>0x3F) speed = 0x3F;
|
||||
return (byte)speed;
|
||||
}
|
||||
return defaultspeed;
|
||||
}
|
||||
|
||||
public static boolean ValidInteger(String x){
|
||||
try{
|
||||
Integer.parseInt(x);
|
||||
return true;
|
||||
} catch (Exception e){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean ValidPortNumber(int port){
|
||||
return port>0 && port<65536;
|
||||
}
|
||||
|
||||
public static boolean ValidPortNumber(String port){
|
||||
try{
|
||||
int portx = Integer.parseInt(port);
|
||||
return ValidPortNumber(portx);
|
||||
} catch (Exception e){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean ValidIPV4(String ipaddress){
|
||||
if (ValidString(ipaddress)){
|
||||
try{
|
||||
InetAddress inet = InetAddress.getByName(ipaddress);
|
||||
if (inet instanceof Inet4Address){
|
||||
if (inet.getHostAddress().equals(ipaddress)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean ValidIPV6(String ipaddress){
|
||||
if (ValidString(ipaddress)){
|
||||
try{
|
||||
InetAddress inet = InetAddress.getByName(ipaddress);
|
||||
if (inet instanceof Inet6Address){
|
||||
if (inet.getHostAddress().equals(ipaddress)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String GetFileName(String filepath){
|
||||
if (ValidString(filepath)){
|
||||
File ff = new File(filepath);
|
||||
if (ff.isFile()){
|
||||
return ff.getName();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static BufferedImage FrameToBufferedImage(Frame frame){
|
||||
return frameConverter.getBufferedImage(frame);
|
||||
}
|
||||
|
||||
public static BufferedImage MatToBufferedImage(Mat mat){
|
||||
return frameConverter.getBufferedImage(matConverter.convert(mat));
|
||||
}
|
||||
|
||||
public static String BufferedImageToBase64(BufferedImage image){
|
||||
if (image!=null){
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try{
|
||||
javax.imageio.ImageIO.write(image, "jpg", baos);
|
||||
baos.flush();
|
||||
byte[] imageInByte = baos.toByteArray();
|
||||
baos.close();
|
||||
return java.util.Base64.getEncoder().encodeToString(imageInByte);
|
||||
} catch (Exception e){
|
||||
Logger.error("Error converting BufferedImage to Base64: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static @NotNull Properties LoadProperties(String filename){
|
||||
try{
|
||||
InputStream is = new FileInputStream(filename);
|
||||
Properties prop = new Properties();
|
||||
prop.load(is);
|
||||
return prop;
|
||||
} catch (Exception e){
|
||||
Logger.error("Error loading properties file: "+e.getMessage());
|
||||
}
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
public static boolean SaveProperties(Properties prop, String filename){
|
||||
try{
|
||||
OutputStream os = new FileOutputStream(filename);
|
||||
prop.store(os, null);
|
||||
return true;
|
||||
} catch (Exception e){
|
||||
Logger.error("Error saving properties file: "+e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String GetConfigAudioFile(int index){
|
||||
Properties config = LoadProperties("config.properties");
|
||||
String key = String.format("AudioFile%02d", index);
|
||||
return config.getProperty(key, null);
|
||||
}
|
||||
|
||||
public static Mat ResizeMat(Mat source, int width, int height){
|
||||
Size sz = new Size(width, height);
|
||||
Mat dest = new Mat();
|
||||
if (useOpenCL){
|
||||
UMat src = new UMat();
|
||||
source.copyTo(src);
|
||||
UMat dst = new UMat();
|
||||
opencv_imgproc.resize(src, dst, sz);
|
||||
dst.copyTo(dest);
|
||||
} else {
|
||||
opencv_imgproc.resize(source, dest, sz);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
public static Frame ResizeFrame(Frame source, int width, int height){
|
||||
Mat mat = matConverter.convertToMat(source);
|
||||
Mat resized = ResizeMat(mat, width, height);
|
||||
return matConverter.convert(resized);
|
||||
}
|
||||
}
|
||||
165
src/main/java/SBC/GPIO.java
Normal file
165
src/main/java/SBC/GPIO.java
Normal file
@@ -0,0 +1,165 @@
|
||||
package SBC;
|
||||
|
||||
import com.sun.jna.Platform;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class GPIO {
|
||||
|
||||
private static final Path gpioPath = Path.of("/sys/class/gpio");
|
||||
private static final Path gpioExportPath = Path.of("/sys/class/gpio/export");
|
||||
private static final Path gpioUnexportPath = Path.of("/sys/class/gpio/unexport");
|
||||
|
||||
|
||||
public static boolean IsRaspberry64(){
|
||||
if (Platform.isLinux()){
|
||||
if (Platform.isARM()){
|
||||
if (Platform.is64Bit()){
|
||||
if (gpioPath.toFile().isDirectory()){
|
||||
if (gpioExportPath.toFile().isFile()){
|
||||
if (gpioUnexportPath.toFile().isFile()){
|
||||
return true;
|
||||
} else Logger.error("GPIO unexport path is not found");
|
||||
} else Logger.error("GPIO export path is not found");
|
||||
} else Logger.error("GPIO path is not found");
|
||||
} else Logger.info("Device is not 64 bit");
|
||||
} else Logger.info("Device is not ARM");
|
||||
} else Logger.info("OS is not Linux");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the pin is already exported
|
||||
* @param pin GPIO pin number
|
||||
* @return true if the pin is already exported
|
||||
*/
|
||||
public static boolean GpioPinExists(int pin){
|
||||
Path pinPath = gpioPath.resolve("gpio"+pin);
|
||||
return pinPath.toFile().isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the pin
|
||||
* @param pin GPIO pin number
|
||||
* @return true if the pin is successfully exported
|
||||
*/
|
||||
public static boolean ExportPin(int pin){
|
||||
try{
|
||||
if (Files.isWritable(gpioExportPath)){
|
||||
Files.write(gpioExportPath, String.valueOf(pin).getBytes());
|
||||
Logger.info("Pin "+pin+" exported");
|
||||
return GpioPinExists(pin);
|
||||
} else Logger.error("GPIO export path is not writable");
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to export pin: "+pin+", Message: "+e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unexport the pin
|
||||
* @param pin GPIO pin number
|
||||
* @return true if the pin is successfully unexported
|
||||
*/
|
||||
public static boolean UnexportPin(int pin){
|
||||
if (Files.isWritable(gpioUnexportPath)){
|
||||
try{
|
||||
Files.write(gpioUnexportPath, String.valueOf(pin).getBytes());
|
||||
Logger.info("Pin "+pin+" unexported");
|
||||
return true;
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to unexport pin: "+pin+", Message: "+e.getMessage());
|
||||
}
|
||||
} else Logger.error("GPIO unexport path is not writable");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Direction of the pin
|
||||
* @param pin GPIO pin number
|
||||
* @return "in" if the pin is input, "out" if the pin is output, "unknown" if the direction is unknown
|
||||
*/
|
||||
public static String GetPinDirection(int pin){
|
||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("direction");
|
||||
if (pinPath.toFile().isFile()){
|
||||
if (Files.isReadable(pinPath)){
|
||||
try{
|
||||
return Files.readString(pinPath).trim();
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to read pin direction: "+pin+", Message: "+e.getMessage());
|
||||
}
|
||||
} else Logger.error("Pin direction file is not readable: "+pin);
|
||||
} else Logger.error("Pin direction file not found: "+pin);
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the direction of the pin
|
||||
* @param pin GPIO pin number
|
||||
* @param direction "in" for input, "out" for output
|
||||
* @return true if the direction is successfully set
|
||||
*/
|
||||
public static boolean SetPinDirection(int pin, String direction){
|
||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("direction");
|
||||
if (pinPath.toFile().isFile()){
|
||||
if (Files.isWritable(pinPath)){
|
||||
direction = direction.trim().toLowerCase();
|
||||
if ("in".equals(direction) || "out".equals(direction)){
|
||||
try{
|
||||
Files.write(pinPath, direction.getBytes());
|
||||
Logger.info("Pin "+pin+" direction set to "+direction);
|
||||
return true;
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to set pin direction: "+pin+", Message: "+e.getMessage());
|
||||
}
|
||||
} else Logger.error("Invalid direction: "+direction);
|
||||
} else Logger.error("Pin direction file is not writable: "+pin);
|
||||
} else Logger.error("Pin direction file not found: "+pin);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the output pin
|
||||
* @param pin GPIO pin number
|
||||
* @param isON true to set the pin value to 1, false to set the pin value to 0
|
||||
* @return true if the value is successfully set
|
||||
*/
|
||||
public static boolean SetValue(int pin, boolean isON){
|
||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("value");
|
||||
if (pinPath.toFile().isFile()){
|
||||
if (Files.isWritable(pinPath)){
|
||||
try{
|
||||
Files.write(pinPath, isON?"1".getBytes():"0".getBytes());
|
||||
Logger.info("Pin "+pin+" value set to "+(isON?"1":"0"));
|
||||
return true;
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to set pin value: "+pin+", Message: "+e.getMessage());
|
||||
}
|
||||
} else Logger.error("Pin value file is not writable: "+pin);
|
||||
} else Logger.error("Pin value file not found: "+pin);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the pin
|
||||
* @param pin GPIO pin number
|
||||
* @return "1" if the pin value is 1, "0" if the pin value is 0, "unknown" if the value is unknown
|
||||
*/
|
||||
public static String GetValue(int pin){
|
||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("value");
|
||||
if (pinPath.toFile().isFile()){
|
||||
if (Files.isReadable(pinPath)){
|
||||
try{
|
||||
return Files.readString(pinPath).trim();
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to read pin value: "+pin+", Message: "+e.getMessage());
|
||||
}
|
||||
} else Logger.error("Pin value file is not readable: "+pin);
|
||||
} else Logger.error("Pin value file not found: "+pin);
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
38
src/main/java/Web/SettingInfo.java
Normal file
38
src/main/java/Web/SettingInfo.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package Web;
|
||||
|
||||
import Other.SomeCodes;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class SettingInfo {
|
||||
public String[] AudioFiles;
|
||||
public String AudioFile1;
|
||||
public String AudioFile2;
|
||||
public String AudioFile3;
|
||||
public String AudioFile4;
|
||||
public String AudioFile5;
|
||||
public String CameraIP;
|
||||
public String CameraPort;
|
||||
public String CameraUsername;
|
||||
public String CameraPassword;
|
||||
public String LoginUsername;
|
||||
public String LoginPassword;
|
||||
|
||||
public static SettingInfo getInstance() {
|
||||
SettingInfo settingInfo = new SettingInfo();
|
||||
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||
settingInfo.AudioFiles = SomeCodes.GetAudioFiles();
|
||||
settingInfo.AudioFile1 = prop.getProperty("AudioFile01","").trim();
|
||||
settingInfo.AudioFile2 = prop.getProperty("AudioFile02","").trim();
|
||||
settingInfo.AudioFile3 = prop.getProperty("AudioFile03","").trim();
|
||||
settingInfo.AudioFile4 = prop.getProperty("AudioFile04","").trim();
|
||||
settingInfo.AudioFile5 = prop.getProperty("AudioFile05","").trim();
|
||||
settingInfo.CameraIP = prop.getProperty("Camera_ip","").trim();
|
||||
settingInfo.CameraPort = prop.getProperty("Camera_port","").trim();
|
||||
settingInfo.CameraUsername = prop.getProperty("Camera_user","").trim();
|
||||
settingInfo.CameraPassword = prop.getProperty("Camera_password","").trim();
|
||||
settingInfo.LoginUsername = prop.getProperty("WebUsername","").trim();
|
||||
settingInfo.LoginPassword = prop.getProperty("WebPassword","").trim();
|
||||
return settingInfo;
|
||||
}
|
||||
}
|
||||
214
src/main/java/Web/WebServer.java
Normal file
214
src/main/java/Web/WebServer.java
Normal file
@@ -0,0 +1,214 @@
|
||||
package Web;
|
||||
|
||||
import Other.SomeCodes;
|
||||
import io.javalin.Javalin;
|
||||
import io.javalin.http.UploadedFile;
|
||||
import io.javalin.util.JavalinException;
|
||||
import io.javalin.websocket.*;
|
||||
import lombok.extern.java.Log;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static Other.SomeCodes.*;
|
||||
import static io.javalin.apibuilder.ApiBuilder.*;
|
||||
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public class WebServer {
|
||||
private final Javalin app;
|
||||
private final Set<WsContext> connectedWebsocketClients = ConcurrentHashMap.newKeySet();
|
||||
public WebServer(WebsocketEvent event, String webusername, String webpassword){
|
||||
app = Javalin.create(config -> {
|
||||
config.staticFiles.add("/html");
|
||||
config.router.apiBuilder(()-> path("setting", () ->{
|
||||
get(ctx -> ctx.json(SettingInfo.getInstance()));
|
||||
path("audiofile",()-> post(ctx -> {
|
||||
Logger.info("api /setting/audiofile");
|
||||
String audiofile1 = ctx.formParam("1");
|
||||
String audiofile2 = ctx.formParam("2");
|
||||
String audiofile3 = ctx.formParam("3");
|
||||
String audiofile4 = ctx.formParam("4");
|
||||
String audiofile5 = ctx.formParam("5");
|
||||
Logger.info("audiofile1: {}", audiofile1);
|
||||
Logger.info("audiofile2: {}", audiofile2);
|
||||
Logger.info("audiofile3: {}", audiofile3);
|
||||
Logger.info("audiofile4: {}", audiofile4);
|
||||
Logger.info("audiofile5: {}", audiofile5);
|
||||
|
||||
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||
prop.setProperty("audiofile1", audiofile1!=null?audiofile1:"");
|
||||
prop.setProperty("audiofile2", audiofile2!=null?audiofile2:"");
|
||||
prop.setProperty("audiofile3", audiofile3!=null?audiofile3:"");
|
||||
prop.setProperty("audiofile4", audiofile4!=null?audiofile4:"");
|
||||
prop.setProperty("audiofile5", audiofile5!=null?audiofile5:"");
|
||||
if (SaveProperties(prop, "config.properties")){
|
||||
Logger.info("audiofile saved");
|
||||
ctx.status(200);
|
||||
} else {
|
||||
Logger.error("Failed to save audiofile");
|
||||
ctx.status(400);
|
||||
}
|
||||
}));
|
||||
path("uploadaudiofile", ()-> post(ctx -> {
|
||||
UploadedFile file = ctx.uploadedFile("file");
|
||||
if (file!=null){
|
||||
try {
|
||||
Path targetsave = audioPath.resolve(file.filename());
|
||||
Files.copy(file.content(), targetsave);
|
||||
Logger.info("Uploaded file: {}, size: {} saved at {}", file.filename(),file.size(), targetsave);
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to save uploaded file: {}, Message: {}", file.filename(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}));
|
||||
path("weblogin", ()-> post(ctx -> {
|
||||
String username = ctx.formParam("username");
|
||||
String password = ctx.formParam("password");
|
||||
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||
prop.setProperty("WebUsername", ValidString(username)?username:"admin");
|
||||
prop.setProperty("WebPassword", ValidString(password)?password:"bandara");
|
||||
if (SaveProperties(prop, "config.properties")){
|
||||
ctx.status(200);
|
||||
} else {
|
||||
ctx.status(400);
|
||||
}
|
||||
}));
|
||||
path("camera",()-> post(ctx -> {
|
||||
String camera_ip = ctx.formParam("ip");
|
||||
String camera_port = ctx.formParam("port");
|
||||
String camera_username = ctx.formParam("username");
|
||||
String camera_password = ctx.formParam("password");
|
||||
|
||||
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||
prop.setProperty("Camera_ip", ValidString(camera_ip)?camera_ip:"192.168.0.4");
|
||||
prop.setProperty("Camera_port", ValidString(camera_port)?camera_port:"80");
|
||||
prop.setProperty("Camera_user", ValidString(camera_username)?camera_username:"root");
|
||||
prop.setProperty("Camera_password", ValidString(camera_password)?camera_password:"password");
|
||||
if (SaveProperties(prop, "config.properties")){
|
||||
ctx.status(200);
|
||||
} else {
|
||||
ctx.status(400);
|
||||
}
|
||||
}));
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
app.get("/", ctx-> {
|
||||
if (ctx.sessionAttribute("username")==null) {
|
||||
// belum login
|
||||
ctx.redirect("/login.html");
|
||||
} else if (Objects.equals(ctx.sessionAttribute("username"), webusername)){
|
||||
// sudah login
|
||||
ctx.redirect("/index.html");
|
||||
} else {
|
||||
// sudah login tapi bukan username yang benar
|
||||
ctx.redirect("/login.html");
|
||||
}
|
||||
});
|
||||
|
||||
app.before("/index.html", ctx ->{
|
||||
if (ctx.sessionAttribute("username")==null){
|
||||
ctx.redirect("/login.html");
|
||||
}
|
||||
});
|
||||
|
||||
app.before("/setting.html", ctx ->{
|
||||
if (ctx.sessionAttribute("username")==null){
|
||||
ctx.redirect("/login.html");
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/login", ctx ->{
|
||||
String username = ctx.formParam("username");
|
||||
String password = ctx.formParam("password");
|
||||
if (Objects.equals(username, webusername) && Objects.equals(password, webpassword)){
|
||||
ctx.sessionAttribute("username", username);
|
||||
ctx.redirect("/index.html");
|
||||
} else {
|
||||
ctx.redirect("/login.html?error=Invalid username or password");
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/logout", ctx ->{
|
||||
ctx.sessionAttribute("username", null);
|
||||
ctx.redirect("/login.html");
|
||||
});
|
||||
|
||||
app.ws("/ws", ws -> {
|
||||
ws.onConnect(connectws);
|
||||
ws.onClose(closews);
|
||||
//ws.onError(errorws);
|
||||
ws.onMessage(ctx -> {
|
||||
try{
|
||||
//Logger.info("WebSocket message {}", ctx.message());
|
||||
WebsocketCommand command = ctx.messageAsClass(WebsocketCommand.class);
|
||||
if (event!=null) {
|
||||
WebsocketReply reply = event.onWebsocketCommand(command);
|
||||
if (reply!=null) ctx.sendAsClass(reply, WebsocketReply.class);
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Failed to parse WebSocketCommand message: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Object message to all connected websocket clients
|
||||
* @param obj Object to send
|
||||
*/
|
||||
public void SendtoAll(Object obj){
|
||||
connectedWebsocketClients.forEach(wsContext -> wsContext.send(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the web server
|
||||
* @param localip Local IP address to bind
|
||||
* @param port Port to bind
|
||||
*/
|
||||
public void Start(String localip, int port){
|
||||
try{
|
||||
connectedWebsocketClients.forEach(WsContext::closeSession);
|
||||
app.start(localip, port);
|
||||
Logger.info("Web server started at {}:{}", localip, port);
|
||||
} catch (JavalinException e){
|
||||
Logger.error("Web server failed to start: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the web server
|
||||
*/
|
||||
public void Stop(){
|
||||
try{
|
||||
app.stop();
|
||||
Logger.info("Web server stopped");
|
||||
} catch (JavalinException e){
|
||||
Logger.error("Web server failed to stop: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
WsConnectHandler connectws = ws ->{
|
||||
Logger.info("WebSocket connected from {}", ws.host());
|
||||
//ws.headerMap().forEach((key, value) -> Logger.info("HeaderMap {}: {}", key, value));
|
||||
connectedWebsocketClients.add(ws);
|
||||
};
|
||||
|
||||
WsCloseHandler closews = ws ->{
|
||||
Logger.info("WebSocket closed from {}, code {}, reason {}", ws.host(), ws.status(), ws.reason());
|
||||
connectedWebsocketClients.remove(ws);
|
||||
};
|
||||
|
||||
//WsErrorHandler errorws = ws -> Logger.error("WebSocket error from {}, error {}", ws.host(), ws.error());
|
||||
|
||||
|
||||
|
||||
}
|
||||
14
src/main/java/Web/WebsocketCommand.java
Normal file
14
src/main/java/Web/WebsocketCommand.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package Web;
|
||||
|
||||
public class WebsocketCommand {
|
||||
public String command;
|
||||
public String data;
|
||||
public WebsocketCommand(){
|
||||
this.command = "";
|
||||
this.data = "";
|
||||
}
|
||||
public WebsocketCommand(String command, String data){
|
||||
this.command = command;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
6
src/main/java/Web/WebsocketEvent.java
Normal file
6
src/main/java/Web/WebsocketEvent.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package Web;
|
||||
|
||||
public interface WebsocketEvent {
|
||||
String onMessage(String message);
|
||||
WebsocketReply onWebsocketCommand(WebsocketCommand command);
|
||||
}
|
||||
10
src/main/java/Web/WebsocketReply.java
Normal file
10
src/main/java/Web/WebsocketReply.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package Web;
|
||||
|
||||
public class WebsocketReply {
|
||||
public String reply;
|
||||
public String data;
|
||||
public WebsocketReply(String reply, String data){
|
||||
this.reply = reply;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
314
src/main/java/id/co/gtc/Main.java
Normal file
314
src/main/java/id/co/gtc/Main.java
Normal file
@@ -0,0 +1,314 @@
|
||||
package id.co.gtc;
|
||||
|
||||
import Audio.AudioFileProperties;
|
||||
import Audio.AudioPlayer;
|
||||
import Audio.PlaybackEvent;
|
||||
import Camera.PanTiltController;
|
||||
import Camera.RtspEvent;
|
||||
import Camera.RtspGrabber;
|
||||
import Camera.VapixProtocol;
|
||||
import Other.SomeCodes;
|
||||
import Web.WebServer;
|
||||
import Web.WebsocketCommand;
|
||||
import Web.WebsocketEvent;
|
||||
import Web.WebsocketReply;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.opencv.global.opencv_core;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
|
||||
import static Other.SomeCodes.*;
|
||||
|
||||
public class Main {
|
||||
private static AudioPlayer audioPlayer;
|
||||
private static WebServer webServer;
|
||||
private static RtspGrabber rtspGrabber;
|
||||
private static PanTiltController panTiltController;
|
||||
private static AudioFileProperties audioFileProperties;
|
||||
private static VapixProtocol vapixProtocol;
|
||||
|
||||
// Application start from here
|
||||
public static void main(String[] args) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
if (audioPlayer!=null) audioPlayer.Unload();
|
||||
if (webServer!=null) webServer.Stop();
|
||||
if (rtspGrabber!=null) rtspGrabber.Stop();
|
||||
if (panTiltController!=null) panTiltController.Close();
|
||||
if (vapixProtocol!=null) vapixProtocol.Close();
|
||||
}));
|
||||
|
||||
init_properties();
|
||||
init_audiofiles();
|
||||
|
||||
init_audio();
|
||||
init_webserver();
|
||||
init_rtspgrabber();
|
||||
init_pantiltcontroller();
|
||||
init_Vapix();
|
||||
}
|
||||
|
||||
private static void init_properties(){
|
||||
if (ExtractResource("/tinylog.properties", currentDirectory)==null) Logger.error("Failed to extract tinylog.properties");
|
||||
if (ExtractResource("/config.properties", currentDirectory)==null) Logger.error("Failed to extract config.properties");
|
||||
if (ExtractResource("/simplelogger.properties", currentDirectory)==null) Logger.error("Failed to extract simplelogger.properties");
|
||||
}
|
||||
|
||||
private static void init_audiofiles(){
|
||||
if (audioPath.toFile().isDirectory()) {
|
||||
Logger.info("Audio Files Directory exists : "+audioPath);
|
||||
} else {
|
||||
if (audioPath.toFile().mkdirs()) Logger.info("Audio Files Directory created : "+audioPath);
|
||||
}
|
||||
if (ExtractResource("/elangWav.wav", audioPath.toString())==null) Logger.error("Failed to extract elangWav.wav");
|
||||
if (ExtractResource("/gunshotsWav.wav", audioPath.toString())==null) Logger.error("Failed to extract gunshotsWav.wav");
|
||||
if (ExtractResource("/pinkNoiseWav.wav", audioPath.toString())==null) Logger.error("Failed to extract pinkNoiseWav.wav");
|
||||
}
|
||||
|
||||
private static void init_Vapix(){
|
||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||
String ip = config.getProperty("Camera_ip");
|
||||
String port = config.getProperty("Camera_port");
|
||||
String username = config.getProperty("Camera_user");
|
||||
String password = config.getProperty("Camera_password");
|
||||
if (ValidString(ip)){
|
||||
if (ValidInteger(port)){
|
||||
if (ValidString(username)){
|
||||
if (ValidString(password)){
|
||||
vapixProtocol = new VapixProtocol(ip, Integer.parseInt(port), username, password);
|
||||
Logger.info("Camera Product Number: "+vapixProtocol.GetProductNumber());
|
||||
Logger.info("Camera Serial Number: "+vapixProtocol.GetSerialNumber());
|
||||
if (vapixProtocol.PTZEnabled()){
|
||||
Logger.info("PTZ Enabled");
|
||||
} else Logger.error("PTZ Disabled");
|
||||
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
|
||||
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
|
||||
} else Logger.error("Invalid Camera Password");
|
||||
} else Logger.error("Invalid Camera Username");
|
||||
} else Logger.error("Invalid Camera Port");
|
||||
} else Logger.error("Invalid Camera IP");
|
||||
}
|
||||
|
||||
private static void init_pantiltcontroller() {
|
||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||
String portname = config.getProperty("SerialPort");
|
||||
String baudrate = config.getProperty("SerialBaudRate");
|
||||
String PanTiltID = config.getProperty("PanTiltID");
|
||||
if (ValidString(portname)){
|
||||
if (ValidInteger(baudrate)){
|
||||
if (ValidInteger(PanTiltID)){
|
||||
panTiltController = new PanTiltController(portname, Integer.parseInt(baudrate), Integer.parseInt(PanTiltID));
|
||||
}
|
||||
} else Logger.error("Invalid PTZ Baudrate");
|
||||
} else Logger.error("Invalid PTZ Port");
|
||||
}
|
||||
|
||||
private static void init_rtspgrabber() {
|
||||
if (haveOpenCL) opencv_core.setUseOpenCL(true);
|
||||
// check if really activated
|
||||
useOpenCL = opencv_core.useOpenCL();
|
||||
Logger.info("OpenCL available={}, activated={}", haveOpenCL, useOpenCL);
|
||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||
String targetip = config.getProperty("Camera_ip");
|
||||
String rtsppath = config.getProperty("Camera_Rtsp_path");
|
||||
if (ValidString(targetip)){
|
||||
if (ValidString(rtsppath)){
|
||||
rtspGrabber = new RtspGrabber(targetip, rtsppath);
|
||||
|
||||
RtspEvent re = new RtspEvent() {
|
||||
@Override
|
||||
public void onMatReceived(Mat mat) {
|
||||
//TODO : kalau butuh Mat, ambil disini
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFrameReceived(Frame frame) {
|
||||
//TODO : kalau butuh Frame, ambil disini
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBase64Received(String base64) {
|
||||
WebsocketReply wr = new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ base64);
|
||||
webServer.SendtoAll(wr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamingStatusReceived(String status) {
|
||||
WebsocketReply wr = new WebsocketReply("STREAMING STATUS", status);
|
||||
webServer.SendtoAll(wr);
|
||||
}
|
||||
};
|
||||
rtspGrabber.Start(true, 1920, 1080, re);
|
||||
} else Logger.error("Invalid Camera Path");
|
||||
} else Logger.error("Invalid Camera IP");
|
||||
}
|
||||
|
||||
private static void init_audio() {
|
||||
audioPlayer = new AudioPlayer();
|
||||
audioPlayer.DetectOutputDevices();
|
||||
audioPlayer.OpenDevice(1,48000);
|
||||
audioPlayer.setMasterVolume(100);
|
||||
audioPlayer.setPlaybackvolume(100);
|
||||
}
|
||||
|
||||
static PlaybackEvent pe = new PlaybackEvent() {
|
||||
@Override
|
||||
public void onPlaybackStart(AudioFileProperties prop) {
|
||||
Logger.info("Playback started for {}", prop.filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaybackFinished(AudioFileProperties prop) {
|
||||
Logger.info("Playback finished for {}", prop.filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaybackFailure(AudioFileProperties prop, String reason) {
|
||||
Logger.error("Playback failed for {}: {}", prop.filename, reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaybackLooped(AudioFileProperties prop) {
|
||||
Logger.info("Playback looped for {}", prop.filename);
|
||||
}
|
||||
};
|
||||
|
||||
static WebsocketEvent we = new WebsocketEvent() {
|
||||
@Override
|
||||
public String onMessage(String message) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebsocketReply onWebsocketCommand(WebsocketCommand command) {
|
||||
|
||||
byte speed;
|
||||
String cmd = command.command.toUpperCase().trim();
|
||||
switch (cmd){
|
||||
// Pan Tilt Movement Commands
|
||||
case "PAN LEFT" :
|
||||
speed = GetPanTiltSpeed(command.data, (byte)0x20);
|
||||
if (panTiltController!=null) panTiltController.PanLeft(speed);
|
||||
return new WebsocketReply("PAN LEFT", String.valueOf(speed));
|
||||
case "PAN RIGHT" :
|
||||
speed = GetPanTiltSpeed(command.data, (byte)0x20);
|
||||
if (panTiltController!=null) panTiltController.PanRight(speed);
|
||||
return new WebsocketReply("PAN RIGHT", String.valueOf(speed));
|
||||
case "TILT UP" :
|
||||
speed = GetPanTiltSpeed(command.data, (byte)0x20);
|
||||
if (panTiltController!=null) panTiltController.TiltUp(speed);
|
||||
return new WebsocketReply("TILT UP", String.valueOf(speed));
|
||||
case "TILT DOWN" :
|
||||
speed = GetPanTiltSpeed(command.data, (byte)0x20);
|
||||
if (panTiltController!=null) panTiltController.TiltDown(speed);
|
||||
return new WebsocketReply("TILT DOWN", String.valueOf(speed));
|
||||
case "STOP MOVEMENT" :
|
||||
if (panTiltController!=null) panTiltController.StopMovement();
|
||||
return new WebsocketReply("STOP MOVEMENT", "");
|
||||
// Audio Related Commands
|
||||
case "MUTE":
|
||||
audioPlayer.Mute();
|
||||
return new WebsocketReply("MUTE", "");
|
||||
case "UNMUTE":
|
||||
audioPlayer.Unmute();
|
||||
return new WebsocketReply("UNMUTE", "");
|
||||
case "SET VOLUME" :
|
||||
int volume=-1;
|
||||
if (ValidInteger(command.data)){
|
||||
volume = Integer.parseInt(command.data);
|
||||
if (volume<0) volume = 0;
|
||||
if (volume>100) volume = 100;
|
||||
}
|
||||
if (volume>=0){
|
||||
audioPlayer.setPlaybackvolume(volume);
|
||||
return new WebsocketReply("SET VOLUME", String.valueOf(volume));
|
||||
} else return new WebsocketReply("SET VOLUME", "Invalid Volume Value");
|
||||
case "GET VOLUME" :
|
||||
int vol = audioPlayer.getPlaybackvolume();
|
||||
return new WebsocketReply("GET VOLUME", String.valueOf(vol));
|
||||
case "PLAY AUDIO" :
|
||||
if (ValidInteger(command.data)){
|
||||
int id = Integer.parseInt(command.data);
|
||||
String filename = GetConfigAudioFile(id);
|
||||
if (ValidString(filename)){
|
||||
File filetoplay = new File(Path.of(currentDirectory, "audiofiles", filename).toString());
|
||||
if (filetoplay.isFile()){
|
||||
AudioFileProperties afp = audioPlayer.OpenAudioFile(filetoplay);
|
||||
if (afp!=null){
|
||||
audioFileProperties = afp;
|
||||
audioPlayer.PlayAudioFile(afp, true, pe);
|
||||
return new WebsocketReply("PLAY AUDIO", afp.filename);
|
||||
} else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
|
||||
} else return new WebsocketReply("PLAY AUDIO", "Audio file not found : "+filename);
|
||||
} else return new WebsocketReply("PLAY AUDIO", String.format("AudioFile with ID %02d not found", id));
|
||||
} else return new WebsocketReply("PLAY AUDIO", "Invalid Audio ID");
|
||||
case "STOP AUDIO" :
|
||||
if (audioFileProperties!=null){
|
||||
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
|
||||
String filename = audioFileProperties.filename;
|
||||
audioFileProperties = null;
|
||||
return new WebsocketReply("STOP AUDIO", filename);
|
||||
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
|
||||
// ZOOM Related Commands
|
||||
case "GET MAX ZOOM":
|
||||
if (vapixProtocol!=null){
|
||||
return new WebsocketReply("GET MAX ZOOM", String.valueOf(vapixProtocol.GetPTZMaxZoom()));
|
||||
} else return new WebsocketReply("GET MAX ZOOM", "VapixProtocol not initialized");
|
||||
case "GET ZOOM":
|
||||
if (vapixProtocol!=null){
|
||||
return new WebsocketReply("GET ZOOM", String.valueOf(vapixProtocol.GetCurrentZoomValue()));
|
||||
} else return new WebsocketReply("GET ZOOM", "VapixProtocol not initialized");
|
||||
case "SET ZOOM":
|
||||
if (vapixProtocol.PTZEnabled()){
|
||||
if (ValidInteger(command.data)){
|
||||
int zoom = Integer.parseInt(command.data);
|
||||
if (zoom<vapixProtocol.GetPTZMinZoom()) zoom = vapixProtocol.GetPTZMinZoom();
|
||||
if (zoom>vapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
|
||||
if (vapixProtocol.Zoom(1, zoom)){
|
||||
return new WebsocketReply("ZOOM", String.valueOf(zoom));
|
||||
} else return new WebsocketReply("ZOOM", "Failed to zoom");
|
||||
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
|
||||
} else return new WebsocketReply("ZOOM", "Zoom not supported");
|
||||
// Live Streaming Related Commands
|
||||
case "GET BASE64":
|
||||
if (rtspGrabber!=null){
|
||||
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastBase64());
|
||||
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||
case "GET RESOLUTION":
|
||||
if (vapixProtocol!=null){
|
||||
int[] res = vapixProtocol.GetCurrentResolution(1);
|
||||
return new WebsocketReply("GET RESOLUTION", String.format("%dx%d", res[0], res[1]));
|
||||
} else return new WebsocketReply("GET RESOLUTION", "VapixProtocol not initialized");
|
||||
case "SET VIDEO QUALITY":
|
||||
if (Objects.equals(command.data,"HQ")){
|
||||
if (rtspGrabber!=null) rtspGrabber.ChangeVideoQuality(true);
|
||||
return new WebsocketReply("SET VIDEO QUALITY", "High Quality");
|
||||
} else if (Objects.equals(command.data,"LQ")){
|
||||
if (rtspGrabber!=null) rtspGrabber.ChangeVideoQuality(false);
|
||||
return new WebsocketReply("SET VIDEO QUALITY", "Low Quality");
|
||||
} else return new WebsocketReply("SET VIDEO QUALITY", "Invalid Video Quality");
|
||||
case "STREAMING STATUS":
|
||||
if (rtspGrabber!=null){
|
||||
return new WebsocketReply("STREAMING STATUS", rtspGrabber.GetStreamingStatus());
|
||||
} else return new WebsocketReply("STREAMING STATUS", "RTSP Grabber not initialized");
|
||||
default:
|
||||
return new WebsocketReply("UNKNOWN COMMAND", command.command);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static void init_webserver() {
|
||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||
String webusername = config.getProperty("WebUsername", "admin");
|
||||
String webpassword = config.getProperty("WebPassword", "bandara");
|
||||
String webhost = config.getProperty("WebHost","0.0.0.0");
|
||||
String webport = config.getProperty("WebPort","8080");
|
||||
|
||||
webServer = new WebServer(we, webusername, webpassword);
|
||||
webServer.Start(webhost, Integer.parseInt(webport));
|
||||
}
|
||||
}
|
||||
9
tinylog.properties
Normal file
9
tinylog.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
//writer = rolling file
|
||||
writer = console
|
||||
writer.file = logs/{date:yyyy-MM-dd}.log
|
||||
writer.format = {date:yyyy-MM-dd HH:mm:ss} {level}: {class}.{method}() {message}
|
||||
writer.policies = daily
|
||||
writer.buffered = true
|
||||
writer.charset = UTF-8
|
||||
writer.level = info
|
||||
writer.append = true
|
||||
Reference in New Issue
Block a user