Add more functions
This commit is contained in:
@@ -10,7 +10,7 @@ AudioFile03 = pinkNoiseWav.wav
|
|||||||
AudioFile04 = 04.mp3
|
AudioFile04 = 04.mp3
|
||||||
AudioFile05 = 05.mp3
|
AudioFile05 = 05.mp3
|
||||||
AudioVolumeOutput = 100
|
AudioVolumeOutput = 100
|
||||||
SerialPort = /dev/ttyUSB0
|
SerialPort = /dev/ttyAMA0
|
||||||
SerialBaudRate = 9600
|
SerialBaudRate = 9600
|
||||||
PanTiltID = 1
|
PanTiltID = 1
|
||||||
WebUsername = admin
|
WebUsername = admin
|
||||||
|
|||||||
@@ -40,23 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</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 -->
|
<!-- SECTION 2 -->
|
||||||
<div class="container-fluid container3">
|
<div class="container-fluid container3">
|
||||||
@@ -66,13 +50,43 @@
|
|||||||
<img id="camerastream" src="public/images/not-available.png" class="img-cctv class100" alt="">
|
<img id="camerastream" src="public/images/not-available.png" class="img-cctv class100" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6 col-sm-6 col-md-8 col-lg-8 col-xl-8">
|
<div class="col-12 col-sm-4 col-md-4 col-lg-4 col-xl-4">
|
||||||
<p id="streaming_status">No Status</p>
|
<p id="streaming_status">No Status</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-sm-6 col-md-4 col-lg-4 col-xl-4">
|
<div class="col-12 col-sm-4 col-md-5 col-lg-5 col-xl-5">
|
||||||
<div class="form-check form-switch">
|
<!-- <p id="system_information"> System Information </p>-->
|
||||||
<input class="form-check-input" type="checkbox" role="switch" id="quality_video" onchange="change_video_quality()">
|
<div class="row">
|
||||||
<label class="form-check-label" for="quality_video">High Quality Video</label>
|
<div class="col">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="fa-solid fa-microchip icon-system"></span>
|
||||||
|
<p id="cpu_usage" class="padleft">100 %</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="fa-solid fa-temperature-half icon-system"></span>
|
||||||
|
<p id="cpu_temperature" class="padleft">55 °C</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="fa-solid fa-memory icon-system"></span>
|
||||||
|
<p id="ram_usage" class="padleft">15 %</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-4 col-md-3 col-lg-3 col-xl-3">
|
||||||
|
<!-- <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">HQ</label>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<div class="container align-right">
|
||||||
|
<label for="quality_video" class="toggle-label">LQ</label>
|
||||||
|
<input type="checkbox" class="toggle-switch" id="quality_video" onchange="change_video_quality()">
|
||||||
|
<label for="quality_video" class="toggle-label">HQ</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,10 +14,32 @@ let camerastream;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function(){
|
let files = [null,null,null,null,null];
|
||||||
camerastream = document.getElementById("camerastream");
|
|
||||||
|
|
||||||
setInterval(function (){
|
let getbase64handle;
|
||||||
|
let getsysteminfohandle;
|
||||||
|
|
||||||
|
window.addEventListener("unload",function (){
|
||||||
|
clearInterval(getbase64handle);
|
||||||
|
clearInterval(getsysteminfohandle);
|
||||||
|
if (ws.readyState === WebSocket.OPEN){
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
command: "STOP AUDIO",
|
||||||
|
data: 0
|
||||||
|
}));
|
||||||
|
|
||||||
|
// wait a while
|
||||||
|
const start = Date.now();
|
||||||
|
while(Date.now()-start<200){}
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.close();
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener("load", function (){
|
||||||
|
camerastream = document.getElementById("camerastream");
|
||||||
|
// Update camera stream every 50ms / 20fps
|
||||||
|
getbase64handle = setInterval(function (){
|
||||||
if (ws.readyState === WebSocket.OPEN){
|
if (ws.readyState === WebSocket.OPEN){
|
||||||
ws.send(JSON.stringify({
|
ws.send(JSON.stringify({
|
||||||
command: "GET BASE64",
|
command: "GET BASE64",
|
||||||
@@ -25,7 +47,16 @@ document.addEventListener("DOMContentLoaded", function(){
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
} else update_camerastream(null);
|
} else update_camerastream(null);
|
||||||
},10);
|
},1000/15);
|
||||||
|
|
||||||
|
getsysteminfohandle = setInterval(function (){
|
||||||
|
if (ws.readyState === WebSocket.OPEN){
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
command: "GET SYSTEM INFO",
|
||||||
|
data: 0
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
ws = new WebSocket("/ws");
|
ws = new WebSocket("/ws");
|
||||||
|
|
||||||
@@ -49,6 +80,10 @@ document.addEventListener("DOMContentLoaded", function(){
|
|||||||
command: "GET RESOLUTION",
|
command: "GET RESOLUTION",
|
||||||
data: 0
|
data: 0
|
||||||
}));
|
}));
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
command: "GET AUDIOFILES",
|
||||||
|
data: 0
|
||||||
|
}))
|
||||||
|
|
||||||
}
|
}
|
||||||
ws.onmessage = function(event){
|
ws.onmessage = function(event){
|
||||||
@@ -63,7 +98,10 @@ document.addEventListener("DOMContentLoaded", function(){
|
|||||||
update_camerastream(dx.data);
|
update_camerastream(dx.data);
|
||||||
} else update_camerastream(null);
|
} else update_camerastream(null);
|
||||||
if (dx.additional && dx.additional.length>0){
|
if (dx.additional && dx.additional.length>0){
|
||||||
$('#streaming_status').html(dx.additional);
|
let stat = JSON.parse(dx.additional);
|
||||||
|
if (Array.isArray(stat) && stat.length === 3){
|
||||||
|
$('#streaming_status').html("Streaming at "+stat[0]+"x"+stat[1]+" "+stat[2]+"fps");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "SET VOLUME":
|
case "SET VOLUME":
|
||||||
@@ -75,15 +113,13 @@ document.addEventListener("DOMContentLoaded", function(){
|
|||||||
break;
|
break;
|
||||||
case "GET MAX ZOOM":
|
case "GET MAX ZOOM":
|
||||||
console.log("Get Max Zoom: "+dx.data);
|
console.log("Get Max Zoom: "+dx.data);
|
||||||
$('#zoom')
|
let zoom = document.getElementById("zoom");
|
||||||
.attr("max", dx.data)
|
zoom.min = 1;
|
||||||
.attr("min", 1);
|
zoom.max = dx.data;
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "GET ZOOM":
|
case "GET ZOOM":
|
||||||
|
document.getElementById("zoom").value = dx.data;
|
||||||
console.log("Get Zoom: "+dx.data);
|
console.log("Get Zoom: "+dx.data);
|
||||||
$('#zoom').val(dx.data);
|
|
||||||
break;
|
break;
|
||||||
case "GET RESOLUTION":
|
case "GET RESOLUTION":
|
||||||
console.log("Get Resolution: "+dx.data);
|
console.log("Get Resolution: "+dx.data);
|
||||||
@@ -114,11 +150,60 @@ document.addEventListener("DOMContentLoaded", function(){
|
|||||||
break;
|
break;
|
||||||
case "STOP AUDIO":
|
case "STOP AUDIO":
|
||||||
console.log("Stop Audio");
|
console.log("Stop Audio");
|
||||||
$('#status_player').html("Stop Playback");
|
document.getElementById("status_player").innerHTML = "Stop Playback";
|
||||||
break;
|
break;
|
||||||
case 'SET VIDEO QUALITY':
|
case 'SET VIDEO QUALITY':
|
||||||
console.log("Set Video Quality: "+dx.data);
|
console.log("Set Video Quality: "+dx.data);
|
||||||
break;
|
break;
|
||||||
|
case "GET SYSTEM INFO":
|
||||||
|
//console.log("Get System Info: "+dx.data);
|
||||||
|
/**
|
||||||
|
* @type {{cpu_temperature: string, ram_usage: string, cpu: string, cpu0: string, cpu1: string, cpu2: string, cpu3: string}} systeminfo
|
||||||
|
*/
|
||||||
|
let systeminfo = JSON.parse(dx.data);
|
||||||
|
if (systeminfo.cpu_temperature && systeminfo.cpu_temperature.length>0) $('#cpu_temperature').html(`${systeminfo.cpu_temperature} °C`);
|
||||||
|
if (systeminfo.cpu && systeminfo.cpu.length>0) $('#cpu_usage').html(`${systeminfo.cpu} %`);
|
||||||
|
if (systeminfo.ram_usage && systeminfo.ram_usage.length>0) $('#ram_usage').html(`${systeminfo.ram_usage} %`);
|
||||||
|
break;
|
||||||
|
case "GET AUDIOFILES":
|
||||||
|
console.log("Get Audio Files: "+dx.data);
|
||||||
|
let audiofiles = JSON.parse(dx.data);
|
||||||
|
if (audiofiles.preset1 && audiofiles.preset1.length>0 && audiofiles.preset1!== "null") {
|
||||||
|
files[0] = audiofiles.preset1;
|
||||||
|
play_on(1);
|
||||||
|
} else {
|
||||||
|
files[0] = null;
|
||||||
|
play_off(1);
|
||||||
|
}
|
||||||
|
if (audiofiles.preset2 && audiofiles.preset2.length>0 && audiofiles.preset2!== "null") {
|
||||||
|
files[1] = audiofiles.preset2;
|
||||||
|
play_on(2);
|
||||||
|
} else {
|
||||||
|
files[1] = null;
|
||||||
|
play_off(2);
|
||||||
|
}
|
||||||
|
if (audiofiles.preset3 && audiofiles.preset3.length>0 && audiofiles.preset3!== "null") {
|
||||||
|
files[2] = audiofiles.preset3;
|
||||||
|
play_on(3);
|
||||||
|
} else {
|
||||||
|
files[2] = null;
|
||||||
|
play_off(3);
|
||||||
|
}
|
||||||
|
if (audiofiles.preset4 && audiofiles.preset4.length>0 && audiofiles.preset4!== "null") {
|
||||||
|
files[3] = audiofiles.preset4;
|
||||||
|
play_on(4);
|
||||||
|
} else {
|
||||||
|
files[3] = null;
|
||||||
|
play_off(4);
|
||||||
|
}
|
||||||
|
if (audiofiles.preset5 && audiofiles.preset5.length>0 && audiofiles.preset5!== "null") {
|
||||||
|
files[4] = audiofiles.preset5;
|
||||||
|
play_on(5);
|
||||||
|
} else {
|
||||||
|
files[4] = null;
|
||||||
|
play_off(5);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +217,9 @@ document.addEventListener("DOMContentLoaded", function(){
|
|||||||
|
|
||||||
set_pan_speed(32);
|
set_pan_speed(32);
|
||||||
set_tilt_speed(32);
|
set_tilt_speed(32);
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update camera stream
|
* Update camera stream
|
||||||
@@ -176,7 +263,9 @@ function show_stop_and_hide_play(index){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function allplay(){
|
function allplay(){
|
||||||
for (let i = 0; i < 5; i++) play_on(i+1);
|
for (let i = 0; i < 5; i++) {
|
||||||
|
if (files[i]) play_on(i+1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function play_button(index){
|
function play_button(index){
|
||||||
|
|||||||
@@ -48,74 +48,72 @@
|
|||||||
<h5 class="text-md-center">Audio Files</h5>
|
<h5 class="text-md-center">Audio Files</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body bg-gray">
|
<div class="card-body bg-gray">
|
||||||
<form action="/setting/audiofile" method="post">
|
<!-- PRESET 1-->
|
||||||
<!-- PRESET 1-->
|
<div class="row mt--2">
|
||||||
<div class="row mt--2">
|
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
<p>Preset 1</p>
|
||||||
<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>
|
</div>
|
||||||
<!-- PRESET 2-->
|
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||||
<div class="row mt-2">
|
<select id="preset1" class="form-control class100">
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
<option>Option 1</option>
|
||||||
<p>Preset 2</p>
|
<option>Option 2</option>
|
||||||
</div>
|
</select>
|
||||||
<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>
|
</div>
|
||||||
<!-- PRESET 3-->
|
</div>
|
||||||
<div class="row mt-2">
|
<!-- PRESET 2-->
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
<div class="row mt-2">
|
||||||
<p>Preset 3</p>
|
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||||
</div>
|
<p>Preset 2</p>
|
||||||
<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>
|
</div>
|
||||||
<!-- PRESET 4-->
|
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||||
<div class="row mt-2">
|
<select id="preset2" class="form-control class100">
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
<option>Option 1</option>
|
||||||
<p>Preset 4</p>
|
<option>Option 2</option>
|
||||||
</div>
|
</select>
|
||||||
<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>
|
</div>
|
||||||
<!-- PRESET 5-->
|
</div>
|
||||||
<div class="row mt-2">
|
<!-- PRESET 3-->
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
<div class="row mt-2">
|
||||||
<p>Preset 5</p>
|
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||||
</div>
|
<p>Preset 3</p>
|
||||||
<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>
|
||||||
<div class="row mt-2">
|
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6">
|
||||||
<div class="col-6"></div>
|
<select id="preset3" class="form-control class100">
|
||||||
<div class="col-6">
|
<option>Option 1</option>
|
||||||
<button id="save_audio" type="submit" class="btn btn-primary class100" onclick="save_audio()">SAVE</button>
|
<option>Option 2</option>
|
||||||
</div>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</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" class="btn btn-primary class100" onclick="save_audio()">SAVE</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -130,7 +128,7 @@
|
|||||||
<p> Upload audio files</p>
|
<p> Upload audio files</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-sm-6 col-md-4 col-lg-4 col-xl-4">
|
<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">
|
<input class="form-control" type="file" name="file" required title="Select Audio File">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-sm-6 col-md-2 col-lg-2 col-xl-2">
|
<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>
|
<button id="uploadd_file" type="submit" class="btn btn-dark class100">Upload</button>
|
||||||
@@ -146,53 +144,51 @@
|
|||||||
<h5 class="text-center">Camera</h5>
|
<h5 class="text-center">Camera</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body bg-gray">
|
<div class="card-body bg-gray">
|
||||||
<form action="/setting/camera" method="post">
|
<div class="row mt-2">
|
||||||
<div class="row mt-2">
|
<div class="col-6">
|
||||||
<div class="col-6">
|
<p>IP Address</p>
|
||||||
<p>IP Address</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input id="setting_ip" class="form-control" title="IP Address">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-2">
|
<div class="col-6">
|
||||||
<div class="col-6">
|
<input id="setting_ip" name="ip" class="form-control" title="IP Address">
|
||||||
<p>Port</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input id="setting_port" class="form-control" title="Port">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<p>Port</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input id="setting_port" name="port" class="form-control" title="Port">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mt-2">
|
<div class="row mt-2">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<p>Username</p>
|
<p>Username</p>
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input id="setting_username" class="form-control" title="Username">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input id="setting_username" name="username" class="form-control" title="Username">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mt-2">
|
<div class="row mt-2">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<p>Password</p>
|
<p>Password</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="password" id="setting_password" class="form-control" title="Password">
|
<input type="password" id="setting_password" name="password" class="form-control" title="Password">
|
||||||
<span class="input-group-text" onclick="cameraPassword()">
|
<span class="input-group-text" onclick="cameraPassword()">
|
||||||
<i class="fa-solid fa-eye" id="icon_camera"></i>
|
<i class="fa-solid fa-eye" id="icon_camera"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-2">
|
</div>
|
||||||
<div class="col-6"></div>
|
<div class="row mt-2">
|
||||||
<div class="col-6">
|
<div class="col-6"></div>
|
||||||
<button id="save_camera" type="submit" class="btn btn-primary class100" onclick="save_camera()">SAVE</button>
|
<div class="col-6">
|
||||||
</div>
|
<button id="save_camera" class="btn btn-primary class100" onclick="save_camera()">SAVE</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -201,48 +197,46 @@
|
|||||||
<h5 class="text-center">Login</h5>
|
<h5 class="text-center">Login</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body bg-gray">
|
<div class="card-body bg-gray">
|
||||||
<form action="/setting/weblogin" method="post">
|
<div class="row mt-2">
|
||||||
<div class="row mt-2">
|
<div class="col-6">
|
||||||
<div class="col-6">
|
<p>Username</p>
|
||||||
<p>Username</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<input id="login_username" class="form-control" title="Username">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-2">
|
<div class="col-6">
|
||||||
<div class="col-6">
|
<input id="login_username" class="form-control" title="Username">
|
||||||
<p>Password</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="row mt-2">
|
||||||
<div class="input-group">
|
<div class="col-6">
|
||||||
<input type="password" id="edit_password" class="form-control" title="Password">
|
<p>Password</p>
|
||||||
<span class="input-group-text" onclick="showPassword()">
|
</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>
|
<i class="fa-solid fa-eye" id="icon_password"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-2">
|
</div>
|
||||||
<div class="col-6">
|
<div class="row mt-2">
|
||||||
<p>Confirm Password</p>
|
<div class="col-6">
|
||||||
</div>
|
<p>Confirm Password</p>
|
||||||
<div class="col-6">
|
</div>
|
||||||
<div class="input-group">
|
<div class="col-6">
|
||||||
<input type="password" id="confirm_password" class="form-control" title="Confirm Password">
|
<div class="input-group">
|
||||||
<span class="input-group-text" onclick="showConfirm()">
|
<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>
|
<i class="fa-solid fa-eye" id="icon_confirm"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-2">
|
</div>
|
||||||
<div class="col-6"></div>
|
<div class="row mt-2">
|
||||||
<div class="col-6">
|
<div class="col-6"></div>
|
||||||
<button id="save_login" type="submit" class="btn btn-primary class100" onclick="save_login()">SAVE</button>
|
<div class="col-6">
|
||||||
</div>
|
<button id="save_login" class="btn btn-primary class100" onclick="save_login()">SAVE</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -54,7 +54,14 @@ function fill_select(index, values){
|
|||||||
*/
|
*/
|
||||||
let preset = document.getElementById("preset"+index);
|
let preset = document.getElementById("preset"+index);
|
||||||
preset.innerHTML = "";
|
preset.innerHTML = "";
|
||||||
|
|
||||||
if (values!=null && values.length>0){
|
if (values!=null && values.length>0){
|
||||||
|
// add empty option
|
||||||
|
let option = document.createElement("option");
|
||||||
|
option.value = "";
|
||||||
|
option.innerText = "";
|
||||||
|
preset.appendChild(option);
|
||||||
|
|
||||||
for (let i = 0; i < values.length; i++) {
|
for (let i = 0; i < values.length; i++) {
|
||||||
const element = values[i];
|
const element = values[i];
|
||||||
let option = document.createElement("option");
|
let option = document.createElement("option");
|
||||||
@@ -109,3 +116,90 @@ function showConfirm() {
|
|||||||
icon.classList.add('fa-eye');
|
icon.classList.add('fa-eye');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function save_audio(){
|
||||||
|
let preset1 = $('#preset1').val();
|
||||||
|
let preset2 = $('#preset2').val();
|
||||||
|
let preset3 = $('#preset3').val();
|
||||||
|
let preset4 = $('#preset4').val();
|
||||||
|
let preset5 = $('#preset5').val();
|
||||||
|
|
||||||
|
if (confirm("Are you sure want to change Audio Preset ?")){
|
||||||
|
fetch("/setting/audiofile", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: new URLSearchParams({preset1: preset1, preset2: preset2, preset3: preset3, preset4: preset4, preset5: preset5})
|
||||||
|
}).then(resp => {
|
||||||
|
if (resp.status === 200) {
|
||||||
|
alert("Success");
|
||||||
|
} else {
|
||||||
|
resp.text().then(text=>alert("Failed to change Audio Preset : "+text));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_camera(){
|
||||||
|
let ip = $('#setting_ip').val();
|
||||||
|
let port = $('#setting_port').val();
|
||||||
|
let username = $('#setting_username').val();
|
||||||
|
let password = $('#setting_password').val();
|
||||||
|
|
||||||
|
if (confirm("Are you sure want to change Camera Information ?")){
|
||||||
|
fetch("/setting/camera", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: new URLSearchParams({ip: ip, port: port, username: username, password: password})
|
||||||
|
}).then(resp => {
|
||||||
|
if (resp.status === 200) {
|
||||||
|
alert("Success");
|
||||||
|
} else {
|
||||||
|
resp.text().then(text => {
|
||||||
|
alert("Failed to change Camera Information : "+text);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_login(){
|
||||||
|
let username = $('#login_username').val();
|
||||||
|
let password = $('#edit_password').val();
|
||||||
|
let confirmpassword = $('#confirm_password').val();
|
||||||
|
if (username.length === 0){
|
||||||
|
alert("Username cannot be empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (password.length === 0){
|
||||||
|
alert("Password cannot be empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (password !== confirmpassword){
|
||||||
|
alert("Password not match");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirm("Are you sure want to change Web Login Information ?")){
|
||||||
|
fetch("/setting/weblogin", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: new URLSearchParams({username: username, password: password})
|
||||||
|
}).then(resp => {
|
||||||
|
if (resp.status === 200) {
|
||||||
|
alert("Success");
|
||||||
|
} else {
|
||||||
|
resp.text().then(text => {
|
||||||
|
alert("Failed to change Web Login Information : "+text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#Fri Nov 08 16:52:01 WIB 2024
|
#Mon Nov 11 16:04:42 WIB 2024
|
||||||
AudioFile01=elangWav.wav
|
AudioFile01=elangWav.wav
|
||||||
AudioFile02=gunshotsWav.wav
|
AudioFile02=gunshotsWav.wav
|
||||||
AudioFile03=pinkNoiseWav.wav
|
AudioFile03=pinkNoiseWav.wav
|
||||||
AudioFile04=04.mp3
|
AudioFile04=
|
||||||
AudioFile05=05.mp3
|
AudioFile05=null
|
||||||
AudioVolumeOutput=100
|
AudioVolumeOutput=100
|
||||||
Camera_Rtsp_path=/axis-media/media.amp
|
Camera_Rtsp_path=/axis-media/media.amp
|
||||||
Camera_ip=192.168.10.17
|
Camera_ip=192.168.10.17
|
||||||
@@ -12,13 +12,8 @@ Camera_port=80
|
|||||||
Camera_user=root
|
Camera_user=root
|
||||||
PanTiltID=1
|
PanTiltID=1
|
||||||
SerialBaudRate=9600
|
SerialBaudRate=9600
|
||||||
SerialPort=/dev/ttyUSB0
|
SerialPort=/dev/ttyAMA0
|
||||||
WebHost=0.0.0.0
|
WebHost=0.0.0.0
|
||||||
WebPassword=bandara
|
WebPassword=bandara
|
||||||
WebPort=8080
|
WebPort=8080
|
||||||
WebUsername=admin
|
WebUsername=admin
|
||||||
audiofile1=
|
|
||||||
audiofile2=
|
|
||||||
audiofile3=
|
|
||||||
audiofile4=
|
|
||||||
audiofile5=
|
|
||||||
|
|||||||
193
pom.xml
193
pom.xml
@@ -8,11 +8,188 @@
|
|||||||
<artifactId>BirdStrikeSoetta</artifactId>
|
<artifactId>BirdStrikeSoetta</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bytedeco</groupId>
|
<groupId>org.bytedeco</groupId>
|
||||||
<artifactId>javacv-platform</artifactId>
|
<artifactId>javacv-platform</artifactId>
|
||||||
<version>1.5.10</version>
|
<version>1.5.8</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>leptonica</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>leptonica-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>artoolkitplus</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>artoolkitplus-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>libdc1394</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>libdc1394-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>libfreenect</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>libfreenect-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>libfreenect2</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>libfreenect2-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>flycapture</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>flycapture-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>librealsense</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>librealsense-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>librealsense2</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>librealsense2-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>videoinput</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>videoinput-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>tesseract</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>tesseract-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<!-- platform dibuangin semua, kemudian tambah sendiri linux-arm64, windows-x86_64, linux-x86_64 -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>javacpp-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>openblas-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>opencv-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>ffmpeg-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- manual tambah untuk platform windows-x86_64 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>opencv</artifactId>
|
||||||
|
<version>4.6.0-1.5.8</version>
|
||||||
|
<classifier>windows-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>javacpp</artifactId>
|
||||||
|
<version>1.5.8</version>
|
||||||
|
<classifier>windows-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>openblas</artifactId>
|
||||||
|
<version>0.3.21-1.5.8</version>
|
||||||
|
<classifier>windows-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>ffmpeg</artifactId>
|
||||||
|
<version>5.1.2-1.5.8</version>
|
||||||
|
<classifier>windows-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<!-- manual tambah untuk platform linux-arm64-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>opencv</artifactId>
|
||||||
|
<version>4.6.0-1.5.8</version>
|
||||||
|
<classifier>linux-arm64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>javacpp</artifactId>
|
||||||
|
<version>1.5.8</version>
|
||||||
|
<classifier>linux-arm64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>openblas</artifactId>
|
||||||
|
<version>0.3.21-1.5.8</version>
|
||||||
|
<classifier>linux-arm64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>ffmpeg</artifactId>
|
||||||
|
<version>5.1.2-1.5.8</version>
|
||||||
|
<classifier>linux-arm64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<!-- manual tambah untuk platform linux-x86_64
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>opencv</artifactId>
|
||||||
|
<version>4.9.0-1.5.10</version>
|
||||||
|
<classifier>linux-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>javacpp</artifactId>
|
||||||
|
<version>1.5.10</version>
|
||||||
|
<classifier>linux-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>openblas</artifactId>
|
||||||
|
<version>0.3.26-1.5.10</version>
|
||||||
|
<classifier>linux-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>ffmpeg</artifactId>
|
||||||
|
<version>6.1.1-1.5.10</version>
|
||||||
|
<classifier>linux-x86_64</classifier>
|
||||||
|
</dependency>
|
||||||
|
-->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.javalin</groupId>
|
<groupId>io.javalin</groupId>
|
||||||
<artifactId>javalin</artifactId>
|
<artifactId>javalin</artifactId>
|
||||||
@@ -52,6 +229,11 @@
|
|||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.17.2</version>
|
<version>2.17.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.11.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -60,4 +242,13 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<extensions>
|
||||||
|
<extension>
|
||||||
|
<groupId>kr.motd.maven</groupId>
|
||||||
|
<artifactId>os-maven-plugin</artifactId>
|
||||||
|
<version>1.7.0</version>
|
||||||
|
</extension>
|
||||||
|
</extensions>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
package Audio;
|
package Audio;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
|
||||||
public class AudioPlayer {
|
public class AudioPlayer {
|
||||||
Bass bass;
|
private final Bass bass;
|
||||||
int deviceid = -1;
|
private int deviceid = -1;
|
||||||
boolean inited = false;
|
@Getter private boolean inited = false;
|
||||||
|
|
||||||
int playbackhandle = 0;
|
int playbackhandle = 0;
|
||||||
float playbackvolume = 1.0f;
|
float playbackvolume = 1.0f;
|
||||||
@@ -48,13 +49,49 @@ public class AudioPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get BASS_DEVICEINFO for a device
|
||||||
|
* @param device device id
|
||||||
|
* @return BASS_DEVICEINFO object or null if failed
|
||||||
|
*/
|
||||||
|
public Bass.BASS_DEVICEINFO GetDeviceInfo(int device){
|
||||||
|
Bass.BASS_DEVICEINFO info = new Bass.BASS_DEVICEINFO();
|
||||||
|
if (bass.BASS_GetDeviceInfo(device, info)){
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find Device ID with Name
|
||||||
|
* @param name device name
|
||||||
|
* @return device id, or -1 if not found
|
||||||
|
*/
|
||||||
|
public int FindDeviceIDWithName(String name){
|
||||||
|
int result = -1;
|
||||||
|
int ii = 1;
|
||||||
|
while(true){
|
||||||
|
Bass.BASS_DEVICEINFO info = new Bass.BASS_DEVICEINFO();
|
||||||
|
if (bass.BASS_GetDeviceInfo(ii, info)){
|
||||||
|
if (info.name.contains(name)){
|
||||||
|
result = ii;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ii++;
|
||||||
|
} else {
|
||||||
|
// gak ada lagi
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open Output Device
|
* Open Output Device
|
||||||
* @param device device id, starts from 1
|
* @param device device id, starts from 1
|
||||||
* @param freq output frequency
|
* @param freq output frequency
|
||||||
* @return true if success
|
* @return true if success
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("UnusedReturnValue")
|
|
||||||
public boolean OpenDevice(int device, int freq){
|
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;
|
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);
|
boolean success = bass.BASS_Init(device, freq, flag);
|
||||||
@@ -69,7 +106,8 @@ public class AudioPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Master Volume
|
* Set Master Output Volume
|
||||||
|
* Master Output Volume related to the system volume (Alsamixer on Linux, Volume Mixer on Windows)
|
||||||
* @param value volume value, 0-100
|
* @param value volume value, 0-100
|
||||||
*/
|
*/
|
||||||
public void setMasterVolume(int value){
|
public void setMasterVolume(int value){
|
||||||
@@ -84,7 +122,8 @@ public class AudioPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Master Volume
|
* Get Master Output Volume
|
||||||
|
* Master Output Volume related to the system volume (Alsamixer on Linux, Volume Mixer on Windows)
|
||||||
* @return 0 - 100, or -1 if failed
|
* @return 0 - 100, or -1 if failed
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@@ -99,6 +138,11 @@ public class AudioPlayer {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Playback Volume
|
||||||
|
* is the volume of the currently playing audio file
|
||||||
|
* @return 0 - 100
|
||||||
|
*/
|
||||||
public int getPlaybackvolume(){
|
public int getPlaybackvolume(){
|
||||||
if (playbackvolume<0)
|
if (playbackvolume<0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -108,6 +152,11 @@ public class AudioPlayer {
|
|||||||
return (int)(playbackvolume*100);
|
return (int)(playbackvolume*100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Playback Volume
|
||||||
|
* is the volume of the currently playing audio file
|
||||||
|
* @param value 0 - 100
|
||||||
|
*/
|
||||||
public void setPlaybackvolume(int value){
|
public void setPlaybackvolume(int value){
|
||||||
if (value<0) value = 0;
|
if (value<0) value = 0;
|
||||||
if (value>100) value = 100;
|
if (value>100) value = 100;
|
||||||
@@ -119,11 +168,17 @@ public class AudioPlayer {
|
|||||||
|
|
||||||
private float lastplaybackvolume = 1.0f;
|
private float lastplaybackvolume = 1.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Playback Volume to 0
|
||||||
|
*/
|
||||||
public void Mute(){
|
public void Mute(){
|
||||||
lastplaybackvolume = playbackvolume;
|
lastplaybackvolume = playbackvolume;
|
||||||
setPlaybackvolume(0);
|
setPlaybackvolume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Playback Volume to last volume before Mute
|
||||||
|
*/
|
||||||
public void Unmute(){
|
public void Unmute(){
|
||||||
setPlaybackvolume((int)lastplaybackvolume*100);
|
setPlaybackvolume((int)lastplaybackvolume*100);
|
||||||
}
|
}
|
||||||
@@ -164,6 +219,12 @@ public class AudioPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Play Audio File
|
||||||
|
* @param prop AudioFileProperties object to play
|
||||||
|
* @param looping set true to loop the audio file
|
||||||
|
* @param event PlaybackEvent object to handle playback event
|
||||||
|
*/
|
||||||
public void PlayAudioFile(AudioFileProperties prop, boolean looping, PlaybackEvent event){
|
public void PlayAudioFile(AudioFileProperties prop, boolean looping, PlaybackEvent event){
|
||||||
if (inited){
|
if (inited){
|
||||||
if (prop!=null){
|
if (prop!=null){
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.bytedeco.javacv.Frame;
|
import org.bytedeco.javacv.Frame;
|
||||||
import org.bytedeco.javacv.FrameGrabber;
|
import org.bytedeco.javacv.FrameGrabber;
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
public class GrabbingTask implements Runnable {
|
public class GrabbingTask implements Runnable {
|
||||||
@Setter private Consumer<String> onMessageUpdate;
|
@Setter private Consumer<String> onMessageUpdate;
|
||||||
@@ -16,13 +17,13 @@ public class GrabbingTask implements Runnable {
|
|||||||
@Setter private Consumer<Frame> onLQFrameUpdate;
|
@Setter private Consumer<Frame> onLQFrameUpdate;
|
||||||
@Setter private Consumer<String> onHQBase64Update;
|
@Setter private Consumer<String> onHQBase64Update;
|
||||||
@Setter private Consumer<String> onLQBase64Update;
|
@Setter private Consumer<String> onLQBase64Update;
|
||||||
|
@Getter private int CaptureFPS = 0;
|
||||||
|
|
||||||
private final AtomicBoolean isGrabbing;
|
private final AtomicBoolean isGrabbing;
|
||||||
private final FrameGrabber grabber;
|
private final FrameGrabber grabber;
|
||||||
@Getter private final int lowquality_width = 640;
|
@Getter private final int lowquality_width = 640;
|
||||||
@Getter private final int lowquality_height = 360;
|
@Getter private final int lowquality_height = 360;
|
||||||
|
|
||||||
|
|
||||||
private void updateMessage(String message) {
|
private void updateMessage(String message) {
|
||||||
if (onMessageUpdate != null) {
|
if (onMessageUpdate != null) {
|
||||||
onMessageUpdate.accept(message);
|
onMessageUpdate.accept(message);
|
||||||
@@ -68,27 +69,44 @@ public class GrabbingTask implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Stop(){
|
||||||
|
isGrabbing.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void grabprocess() throws Exception{
|
||||||
|
grabber.flush();
|
||||||
|
Frame fr =grabber.grab();
|
||||||
|
|
||||||
|
if (fr!=null){
|
||||||
|
updateHQFrame(fr);
|
||||||
|
updateHQBase64(SomeCodes.FrameToBase64(fr));
|
||||||
|
Frame resized = SomeCodes.ResizeFrame(fr, lowquality_width, lowquality_height);
|
||||||
|
updateLQFrame(resized);
|
||||||
|
updateLQBase64(SomeCodes.FrameToBase64(resized));
|
||||||
|
} else updateMessage("Grabber returned null frame");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
isGrabbing.set(true);
|
isGrabbing.set(true);
|
||||||
|
Logger.info("Grabbing Task started");
|
||||||
|
double fps = grabber.getFrameRate();
|
||||||
|
Logger.info("Grabber framerate = {}", fps);
|
||||||
|
long starttick = System.currentTimeMillis();
|
||||||
while (isGrabbing.get()) {
|
while (isGrabbing.get()) {
|
||||||
try {
|
|
||||||
Frame fr =grabber.grab();
|
long elapsed = System.currentTimeMillis() - starttick;
|
||||||
if (fr!=null){
|
starttick = System.currentTimeMillis();
|
||||||
updateHQFrame(fr);
|
//Logger.info("Elapsed time = {} ms", elapsed);
|
||||||
updateHQBase64(SomeCodes.FrameToBase64(fr));
|
if (elapsed>0) CaptureFPS = (int) (1000 / elapsed);
|
||||||
Frame resized = SomeCodes.ResizeFrame(fr, lowquality_width, lowquality_height);
|
try{
|
||||||
updateLQFrame(resized);
|
Thread.yield();
|
||||||
updateLQBase64(SomeCodes.FrameToBase64(resized));
|
grabprocess();
|
||||||
} else updateMessage("Grabber returned null frame");
|
} catch (Exception e){
|
||||||
} catch (Exception e) {
|
Logger.error("Error grabbing frame: "+e.getMessage());
|
||||||
updateMessage("Error grabbing frame: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Logger.info("Grabbing Task stopped");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package Camera;
|
|||||||
import com.fazecast.jSerialComm.SerialPort;
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pan Tilt Controller
|
* Pan Tilt Controller
|
||||||
* Using PelcoD protocol
|
* Using PelcoD protocol
|
||||||
* Source : https://www.commfront.com/pages/pelco-d-protocol-tutorial
|
* Source : <a href="https://www.commfront.com/pages/pelco-d-protocol-tutorial">PelcoD Tutorial</a>
|
||||||
*/
|
*/
|
||||||
public class PanTiltController {
|
public class PanTiltController {
|
||||||
private final SerialPort serialPort;
|
private SerialPort serialPort;
|
||||||
private final byte cameraid;
|
private final byte cameraid;
|
||||||
/**
|
/**
|
||||||
* Open Pan Tilt Controller
|
* Open Pan Tilt Controller
|
||||||
@@ -17,21 +18,38 @@ public class PanTiltController {
|
|||||||
* @param baudrate baudrate used
|
* @param baudrate baudrate used
|
||||||
*/
|
*/
|
||||||
public PanTiltController(String portname, int baudrate, int cameraid){
|
public PanTiltController(String portname, int baudrate, int cameraid){
|
||||||
serialPort = SerialPort.getCommPort(portname);
|
|
||||||
serialPort.setBaudRate(baudrate);
|
|
||||||
this.cameraid = (byte)cameraid;
|
this.cameraid = (byte)cameraid;
|
||||||
if (serialPort.openPort()){
|
SerialPort[] comports = SerialPort.getCommPorts();
|
||||||
Logger.info("Serial Port {} opened successfully at {}", portname, baudrate);
|
if (comports.length>0){
|
||||||
} else {
|
for (SerialPort port : comports){
|
||||||
Logger.info("Failed to open Serial Port {} at {}", portname, baudrate);
|
Logger.info("Available Serial Port : {}", port.getSystemPortName());
|
||||||
}
|
if (port.getSystemPortName().equals(portname)){
|
||||||
|
Logger.info("Serial Port {} found", portname);
|
||||||
|
serialPort = port;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (serialPort!=null){
|
||||||
|
serialPort.setBaudRate(baudrate);
|
||||||
|
if (serialPort.openPort()){
|
||||||
|
Logger.info("Serial Port {} opened successfully at {}", portname, baudrate);
|
||||||
|
} else {
|
||||||
|
Logger.info("Failed to open Serial Port {} at {}", portname, baudrate);
|
||||||
|
}
|
||||||
|
} else Logger.info("Serial Port {} not found", portname);
|
||||||
|
} else Logger.info("No Serial Port found");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close Pan Tilt Controller
|
* Close Pan Tilt Controller
|
||||||
*/
|
*/
|
||||||
public void Close(){
|
public void Close(){
|
||||||
serialPort.closePort();
|
if (serialPort!=null) serialPort.closePort();
|
||||||
Logger.info("Serial Port closed");
|
Logger.info("Serial Port closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,24 +7,59 @@ import org.tinylog.Logger;
|
|||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import static Other.SomeCodes.gson;
|
||||||
|
|
||||||
public class RtspGrabber {
|
public class RtspGrabber {
|
||||||
private final String rtspUrl;
|
private final String rtspUrl;
|
||||||
private FFmpegFrameGrabber grabber;
|
private FFmpegFrameGrabber grabber;
|
||||||
private final AtomicBoolean isGrabbing = new AtomicBoolean(false);
|
private final AtomicBoolean isGrabbing = new AtomicBoolean(false);
|
||||||
private @Getter Frame lastHQFrame = null;
|
private Frame lastHQFrame = null;
|
||||||
private @Getter Frame lastLQFrame = null;
|
private Frame lastLQFrame = null;
|
||||||
private @Getter String lastHQBase64 = null;
|
private String lastHQBase64 = null;
|
||||||
private @Getter String lastLQBase64 = null;
|
private String lastLQBase64 = null;
|
||||||
private @Getter int HQWidth = 0;
|
private @Getter int HQWidth = 0;
|
||||||
private @Getter int HQHeight = 0;
|
private @Getter int HQHeight = 0;
|
||||||
private @Getter int LQWidth = 0;
|
private @Getter int LQWidth = 0;
|
||||||
private @Getter int LQHeight = 0;
|
private @Getter int LQHeight = 0;
|
||||||
|
private GrabbingTask grabbingTask;
|
||||||
|
|
||||||
public RtspGrabber(String ip, String path) {
|
public RtspGrabber(String ip, String path) {
|
||||||
this.rtspUrl = "rtsp://" + ip + path;
|
this.rtspUrl = "rtsp://" + ip + path;
|
||||||
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void setLastHQFrame(Frame frame){
|
||||||
|
lastHQFrame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Frame getLastHQFrame(){
|
||||||
|
return lastHQFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void setLastLQFrame(Frame frame){
|
||||||
|
lastLQFrame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Frame getLastLQFrame(){
|
||||||
|
return lastLQFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void setLastHQBase64(String base64){
|
||||||
|
lastHQBase64 = base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized String getLastHQBase64(){
|
||||||
|
return lastHQBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void setLastLQBase64(String base64){
|
||||||
|
lastLQBase64 = base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized String getLastLQBase64(){
|
||||||
|
return lastLQBase64;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start grabbing frames from rtsp
|
* Start grabbing frames from rtsp
|
||||||
* @param useTcp Use tcp instead of udp
|
* @param useTcp Use tcp instead of udp
|
||||||
@@ -34,11 +69,12 @@ public class RtspGrabber {
|
|||||||
try{
|
try{
|
||||||
grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
|
grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
|
||||||
if (useTcp) grabber.setOption("rtsp_transport", "tcp");
|
if (useTcp) grabber.setOption("rtsp_transport", "tcp");
|
||||||
|
grabber.setTimeout(2000);
|
||||||
grabber.setImageWidth(width);
|
grabber.setImageWidth(width);
|
||||||
grabber.setImageHeight(height);
|
grabber.setImageHeight(height);
|
||||||
grabber.setPixelFormat(avutil.AV_PIX_FMT_BGR24);
|
grabber.setPixelFormat(avutil.AV_PIX_FMT_BGR24);
|
||||||
grabber.start();
|
grabber.start();
|
||||||
|
|
||||||
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
|
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
|
||||||
|
|
||||||
|
|
||||||
@@ -49,7 +85,7 @@ public class RtspGrabber {
|
|||||||
tt.setOnHQFrameUpdate(value -> {
|
tt.setOnHQFrameUpdate(value -> {
|
||||||
if (value!=null){
|
if (value!=null){
|
||||||
if (value.imageWidth>0 && value.imageHeight>0){
|
if (value.imageWidth>0 && value.imageHeight>0){
|
||||||
lastHQFrame = value;
|
setLastHQFrame(value);
|
||||||
HQWidth = value.imageWidth;
|
HQWidth = value.imageWidth;
|
||||||
HQHeight = value.imageHeight;
|
HQHeight = value.imageHeight;
|
||||||
}
|
}
|
||||||
@@ -59,14 +95,15 @@ public class RtspGrabber {
|
|||||||
tt.setOnLQFrameUpdate(value -> {
|
tt.setOnLQFrameUpdate(value -> {
|
||||||
if (value!=null){
|
if (value!=null){
|
||||||
if (value.imageWidth>0 && value.imageHeight>0){
|
if (value.imageWidth>0 && value.imageHeight>0){
|
||||||
lastLQFrame = value;
|
setLastLQFrame(value);
|
||||||
LQWidth = value.imageWidth;
|
LQWidth = value.imageWidth;
|
||||||
LQHeight = value.imageHeight;
|
LQHeight = value.imageHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tt.setOnHQBase64Update(value -> lastHQBase64 = value);
|
tt.setOnHQBase64Update(this::setLastHQBase64);
|
||||||
tt.setOnLQBase64Update(value -> lastLQBase64 = value);
|
tt.setOnLQBase64Update(this::setLastLQBase64);
|
||||||
|
grabbingTask = tt;
|
||||||
new Thread(tt).start();
|
new Thread(tt).start();
|
||||||
|
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
@@ -78,17 +115,28 @@ public class RtspGrabber {
|
|||||||
* Stop grabbing frames
|
* Stop grabbing frames
|
||||||
*/
|
*/
|
||||||
public void Stop(){
|
public void Stop(){
|
||||||
|
isGrabbing.set(false);
|
||||||
|
if (grabbingTask!=null){
|
||||||
|
grabbingTask.Stop();
|
||||||
|
}
|
||||||
|
grabbingTask = null;
|
||||||
if (grabber!=null) {
|
if (grabber!=null) {
|
||||||
try{
|
try{
|
||||||
isGrabbing.set(false);
|
|
||||||
grabber.stop();
|
grabber.stop();
|
||||||
|
grabber.releaseUnsafe();
|
||||||
Logger.info("Grabber stopped");
|
Logger.info("Grabber stopped");
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
Logger.error("Error stopping grabber: " + e.getMessage());
|
Logger.error("Error stopping grabber: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
grabber = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String LQStreamingStatus(){
|
||||||
|
return gson.toJson(new String[]{String.valueOf(LQWidth), String.valueOf(LQHeight) , String.valueOf(grabbingTask.getCaptureFPS())});
|
||||||
|
}
|
||||||
|
|
||||||
|
public String HQStreamingStatus(){
|
||||||
|
return gson.toJson(new String[]{String.valueOf(HQWidth), String.valueOf(HQHeight) , String.valueOf(grabbingTask.getCaptureFPS())});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package Other;
|
package Other;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import org.bytedeco.javacpp.Loader;
|
import org.bytedeco.javacpp.Loader;
|
||||||
import org.bytedeco.javacv.Frame;
|
import org.bytedeco.javacv.Frame;
|
||||||
import org.bytedeco.javacv.Java2DFrameConverter;
|
import org.bytedeco.javacv.Java2DFrameConverter;
|
||||||
@@ -42,6 +43,7 @@ public class SomeCodes {
|
|||||||
public static final boolean haveOpenCL = opencv_core.haveOpenCL();
|
public static final boolean haveOpenCL = opencv_core.haveOpenCL();
|
||||||
public static boolean useOpenCL;
|
public static boolean useOpenCL;
|
||||||
private static final Base64.Encoder base64encoder = java.util.Base64.getEncoder();
|
private static final Base64.Encoder base64encoder = java.util.Base64.getEncoder();
|
||||||
|
public static final Gson gson = new Gson();
|
||||||
|
|
||||||
public static String[] GetAudioFiles(){
|
public static String[] GetAudioFiles(){
|
||||||
try{
|
try{
|
||||||
@@ -49,6 +51,7 @@ public class SomeCodes {
|
|||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
Logger.error("Error getting audio files: "+e.getMessage());
|
Logger.error("Error getting audio files: "+e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,10 +202,15 @@ public class SomeCodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load properties file
|
||||||
|
* @param filename properties file name
|
||||||
|
* @return Properties object loaded, or empty new Properties object if error
|
||||||
|
*/
|
||||||
public static @NotNull Properties LoadProperties(String filename){
|
public static @NotNull Properties LoadProperties(String filename){
|
||||||
try{
|
try{
|
||||||
InputStream is = new FileInputStream(filename);
|
File ff = new File(currentDirectory, filename);
|
||||||
|
InputStream is = new FileInputStream(ff);
|
||||||
Properties prop = new Properties();
|
Properties prop = new Properties();
|
||||||
prop.load(is);
|
prop.load(is);
|
||||||
return prop;
|
return prop;
|
||||||
@@ -212,9 +220,16 @@ public class SomeCodes {
|
|||||||
return new Properties();
|
return new Properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save properties file
|
||||||
|
* @param prop Properties object to save
|
||||||
|
* @param filename properties file name
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public static boolean SaveProperties(Properties prop, String filename){
|
public static boolean SaveProperties(Properties prop, String filename){
|
||||||
try{
|
try{
|
||||||
OutputStream os = new FileOutputStream(filename);
|
File ff = new File(currentDirectory, filename);
|
||||||
|
OutputStream os = new FileOutputStream(ff);
|
||||||
prop.store(os, null);
|
prop.store(os, null);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
@@ -236,6 +251,7 @@ public class SomeCodes {
|
|||||||
UMat src = new UMat();
|
UMat src = new UMat();
|
||||||
source.copyTo(src);
|
source.copyTo(src);
|
||||||
UMat dst = new UMat();
|
UMat dst = new UMat();
|
||||||
|
|
||||||
opencv_imgproc.resize(src, dst, sz);
|
opencv_imgproc.resize(src, dst, sz);
|
||||||
dst.copyTo(dest);
|
dst.copyTo(dest);
|
||||||
} else {
|
} else {
|
||||||
@@ -249,4 +265,19 @@ public class SomeCodes {
|
|||||||
Mat resized = ResizeMat(mat, width, height);
|
Mat resized = ResizeMat(mat, width, height);
|
||||||
return matConverter.convert(resized);
|
return matConverter.convert(resized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if an ip address is reachable
|
||||||
|
* @param ipaddress ip address to check
|
||||||
|
* @return true if valid and reachable, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean IpIsReachable(String ipaddress){
|
||||||
|
try{
|
||||||
|
InetAddress inet = InetAddress.getByName(ipaddress);
|
||||||
|
return inet.isReachable(1000);
|
||||||
|
} catch (Exception e){
|
||||||
|
Logger.error("Error checking ip address: "+e.getMessage());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/main/java/SBC/CpuInfo.java
Normal file
8
src/main/java/SBC/CpuInfo.java
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
public class CpuInfo {
|
||||||
|
public int processorCount;
|
||||||
|
public String revision;
|
||||||
|
public String serial;
|
||||||
|
public String model;
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import org.tinylog.Logger;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class GPIO {
|
public class GPIO {
|
||||||
|
|
||||||
private static final Path gpioPath = Path.of("/sys/class/gpio");
|
private static final Path gpioPath = Path.of("/sys/class/gpio");
|
||||||
@@ -14,19 +13,15 @@ public class GPIO {
|
|||||||
private static final Path gpioUnexportPath = Path.of("/sys/class/gpio/unexport");
|
private static final Path gpioUnexportPath = Path.of("/sys/class/gpio/unexport");
|
||||||
|
|
||||||
|
|
||||||
public static boolean IsRaspberry64(){
|
public static boolean HaveGPIO(){
|
||||||
if (Platform.isLinux()){
|
if (Platform.isLinux()){
|
||||||
if (Platform.isARM()){
|
if (gpioPath.toFile().isDirectory()){
|
||||||
if (Platform.is64Bit()){
|
if (gpioExportPath.toFile().isFile()){
|
||||||
if (gpioPath.toFile().isDirectory()){
|
if (gpioUnexportPath.toFile().isFile()){
|
||||||
if (gpioExportPath.toFile().isFile()){
|
return true;
|
||||||
if (gpioUnexportPath.toFile().isFile()){
|
} else Logger.error("GPIO unexport path is not found");
|
||||||
return true;
|
} else Logger.error("GPIO export path is not found");
|
||||||
} else Logger.error("GPIO unexport path is not found");
|
} else Logger.error("GPIO 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");
|
} else Logger.info("OS is not Linux");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
84
src/main/java/SBC/NetworkTransmitReceiveInfo.java
Normal file
84
src/main/java/SBC/NetworkTransmitReceiveInfo.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static Other.SomeCodes.ValidString;
|
||||||
|
|
||||||
|
public class NetworkTransmitReceiveInfo {
|
||||||
|
public String name;
|
||||||
|
public long bytesReceived;
|
||||||
|
public long packetsReceived;
|
||||||
|
public long errorsReceived;
|
||||||
|
public long droppedReceived;
|
||||||
|
public long fifoReceived;
|
||||||
|
public long frameReceived;
|
||||||
|
public long compressedReceived;
|
||||||
|
public long multicastReceived;
|
||||||
|
public long bytesTransmitted;
|
||||||
|
public long packetsTransmitted;
|
||||||
|
public long errorsTransmitted;
|
||||||
|
public long droppedTransmitted;
|
||||||
|
public long fifoTransmitted;
|
||||||
|
public long collsTransmitted;
|
||||||
|
public long carrierTransmitted;
|
||||||
|
public long compressedTransmitted;
|
||||||
|
public long timetick;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the download speed
|
||||||
|
* @param prev Previous NetworkTransmitReceiveInfo
|
||||||
|
* @param unit Speed unit (KB, MB, GB)
|
||||||
|
* @return Download speed in {unit}/second
|
||||||
|
*/
|
||||||
|
public double RxSpeed(NetworkTransmitReceiveInfo prev, String unit){
|
||||||
|
if (prev!=null){
|
||||||
|
if (Objects.equals(prev.name, name)){
|
||||||
|
long timeDiff = timetick - prev.timetick;
|
||||||
|
if (timeDiff>0){
|
||||||
|
long bytesDiff = bytesReceived - prev.bytesReceived;
|
||||||
|
if (ValidString(unit)) unit = unit.toUpperCase();
|
||||||
|
Double speed = ConvertToUnit(unit, timeDiff, bytesDiff);
|
||||||
|
if (speed != null) return speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Double ConvertToUnit(String unit, long timeDiff, long bytesDiff) {
|
||||||
|
if (bytesDiff>0){
|
||||||
|
double speed = ((double) bytesDiff / timeDiff) * 1000;
|
||||||
|
return switch (unit) {
|
||||||
|
case "KB" -> speed / 1024;
|
||||||
|
case "MB" -> speed / 1024 / 1024;
|
||||||
|
case "GB" -> speed / 1024 / 1024 / 1024;
|
||||||
|
default -> speed;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the upload speed
|
||||||
|
* @param prev Previous NetworkTransmitReceiveInfo
|
||||||
|
* @param unit Speed unit (KB, MB, GB)
|
||||||
|
* @return Upload speed in {unit}/second
|
||||||
|
*/
|
||||||
|
public double TxSpeed(NetworkTransmitReceiveInfo prev, String unit){
|
||||||
|
if (prev!=null){
|
||||||
|
if (Objects.equals(prev.name, name)){
|
||||||
|
long timeDiff = timetick - prev.timetick;
|
||||||
|
if (timeDiff>0){
|
||||||
|
long bytesDiff = bytesTransmitted - prev.bytesTransmitted;
|
||||||
|
if (ValidString(unit)) unit = unit.toUpperCase();
|
||||||
|
Double speed = ConvertToUnit(unit, timeDiff, bytesDiff);
|
||||||
|
if (speed != null) return speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/main/java/SBC/ProcessorStatus.java
Normal file
45
src/main/java/SBC/ProcessorStatus.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
public class ProcessorStatus {
|
||||||
|
public String name;
|
||||||
|
public int user;
|
||||||
|
public int nice;
|
||||||
|
public int system;
|
||||||
|
public int idle;
|
||||||
|
public int iowait;
|
||||||
|
public int irq;
|
||||||
|
public int softirq;
|
||||||
|
public int steal;
|
||||||
|
public int guest;
|
||||||
|
public int guest_nice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate total CPU time
|
||||||
|
* @return Total CPU time
|
||||||
|
*/
|
||||||
|
public int total_time(){
|
||||||
|
return user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate idle CPU time
|
||||||
|
* @return Idle CPU time
|
||||||
|
*/
|
||||||
|
public int idle_time(){
|
||||||
|
return idle + iowait;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate CPU usage percentage
|
||||||
|
* @param prev Previous CPU information
|
||||||
|
* @return CPU usage percentage 0 - 100
|
||||||
|
*/
|
||||||
|
public int cpu_usage(ProcessorStatus prev){
|
||||||
|
if (prev!=null){
|
||||||
|
int total_diff = total_time() - prev.total_time();
|
||||||
|
int idle_diff = idle_time() - prev.idle_time();
|
||||||
|
return (int)(100.0 * (total_diff - idle_diff) / total_diff);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/main/java/SBC/RamInformation.java
Normal file
12
src/main/java/SBC/RamInformation.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
public class RamInformation {
|
||||||
|
public int totalKB;
|
||||||
|
public int usedKB;
|
||||||
|
public int availableKB;
|
||||||
|
public int swapTotalKB;
|
||||||
|
public int swapFreeKB;
|
||||||
|
public double RamUsagePercentage(){
|
||||||
|
return (double) usedKB / totalKB * 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
179
src/main/java/SBC/SystemInformation.java
Normal file
179
src/main/java/SBC/SystemInformation.java
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
import com.sun.jna.Platform;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class SystemInformation {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static int getCPUTemperature() {
|
||||||
|
if (Platform.isLinux()){
|
||||||
|
File ff = new File("/sys/class/thermal/thermal_zone0/temp");
|
||||||
|
if (ff.isFile() && ff.canRead()){
|
||||||
|
try{
|
||||||
|
String value = Files.readString(ff.toPath()).trim();
|
||||||
|
return Integer.parseInt(value) / 1000;
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NetworkTransmitReceiveInfo[] getNetworkTransmitReceiveInfo(){
|
||||||
|
if (Platform.isLinux()){
|
||||||
|
File ff = new File("/proc/net/dev");
|
||||||
|
if (ff.isFile() && ff.canRead()){
|
||||||
|
List<NetworkTransmitReceiveInfo> result = new ArrayList<>();
|
||||||
|
final Pattern pattern = Pattern.compile("\\s+(.*):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
|
||||||
|
try{
|
||||||
|
String[] lines = Files.readString(ff.toPath()).split("\n");
|
||||||
|
for (String line : lines){
|
||||||
|
Matcher m = pattern.matcher(line);
|
||||||
|
if (m.find()){
|
||||||
|
NetworkTransmitReceiveInfo info = new NetworkTransmitReceiveInfo();
|
||||||
|
info.name = m.group(1).trim();
|
||||||
|
info.bytesReceived = Long.parseLong(m.group(2));
|
||||||
|
info.packetsReceived = Long.parseLong(m.group(3));
|
||||||
|
info.errorsReceived = Long.parseLong(m.group(4));
|
||||||
|
info.droppedReceived = Long.parseLong(m.group(5));
|
||||||
|
info.fifoReceived = Long.parseLong(m.group(6));
|
||||||
|
info.frameReceived = Long.parseLong(m.group(7));
|
||||||
|
info.compressedReceived = Long.parseLong(m.group(8));
|
||||||
|
info.multicastReceived = Long.parseLong(m.group(9));
|
||||||
|
info.bytesTransmitted = Long.parseLong(m.group(10));
|
||||||
|
info.packetsTransmitted = Long.parseLong(m.group(11));
|
||||||
|
info.errorsTransmitted = Long.parseLong(m.group(12));
|
||||||
|
info.droppedTransmitted = Long.parseLong(m.group(13));
|
||||||
|
info.fifoTransmitted = Long.parseLong(m.group(14));
|
||||||
|
info.collsTransmitted = Long.parseLong(m.group(15));
|
||||||
|
info.carrierTransmitted = Long.parseLong(m.group(16));
|
||||||
|
info.compressedTransmitted = Long.parseLong(m.group(17));
|
||||||
|
info.timetick = System.currentTimeMillis();
|
||||||
|
result.add(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return result.toArray(new NetworkTransmitReceiveInfo[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new NetworkTransmitReceiveInfo[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CpuInfo getCPUInfo(){
|
||||||
|
CpuInfo result = new CpuInfo();
|
||||||
|
if (Platform.isLinux()){
|
||||||
|
File ff = new File("/proc/cpuinfo");
|
||||||
|
if (ff.isFile() && ff.canRead()){
|
||||||
|
final Pattern pattern = Pattern.compile( "\\s*(.*):\\s*(.*)");
|
||||||
|
try{
|
||||||
|
String[] lines = Files.readString(ff.toPath()).split("\n");
|
||||||
|
for (String line : lines){
|
||||||
|
Matcher m = pattern.matcher(line);
|
||||||
|
if (m.find()){
|
||||||
|
String key = m.group(1).trim();
|
||||||
|
String value = m.group(2).trim();
|
||||||
|
switch (key){
|
||||||
|
case "processor":
|
||||||
|
result.processorCount++;
|
||||||
|
break;
|
||||||
|
case "Revision":
|
||||||
|
result.revision = value;
|
||||||
|
break;
|
||||||
|
case "Serial":
|
||||||
|
result.serial = value;
|
||||||
|
break;
|
||||||
|
case "Model":
|
||||||
|
result.model = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProcessorStatus[] getProcStat(){
|
||||||
|
if (Platform.isLinux()){
|
||||||
|
File ff = new File("/proc/stat");
|
||||||
|
if (ff.isFile() && ff.canRead()){
|
||||||
|
final Pattern pattern = Pattern.compile( "(cpu\\d?)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
|
||||||
|
List<ProcessorStatus> result = new ArrayList<>();
|
||||||
|
try{
|
||||||
|
String[] lines = Files.readString(ff.toPath()).split("\n");
|
||||||
|
for (String line : lines){
|
||||||
|
Matcher m = pattern.matcher(line);
|
||||||
|
if (m.find()){
|
||||||
|
ProcessorStatus info = new ProcessorStatus();
|
||||||
|
info.name = m.group(1).trim();
|
||||||
|
info.user = Integer.parseInt(m.group(2));
|
||||||
|
info.nice = Integer.parseInt(m.group(3));
|
||||||
|
info.system = Integer.parseInt(m.group(4));
|
||||||
|
info.idle = Integer.parseInt(m.group(5));
|
||||||
|
info.iowait = Integer.parseInt(m.group(6));
|
||||||
|
info.irq = Integer.parseInt(m.group(7));
|
||||||
|
info.softirq = Integer.parseInt(m.group(8));
|
||||||
|
info.steal = Integer.parseInt(m.group(9));
|
||||||
|
info.guest = Integer.parseInt(m.group(10));
|
||||||
|
info.guest_nice = Integer.parseInt(m.group(11));
|
||||||
|
result.add(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new ProcessorStatus[0]);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ProcessorStatus[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RamInformation getRAMInformation(){
|
||||||
|
|
||||||
|
RamInformation result = new RamInformation();
|
||||||
|
if (Platform.isLinux()){
|
||||||
|
File ff = new File("/proc/meminfo");
|
||||||
|
if (ff.isFile() && ff.canRead()){
|
||||||
|
final Pattern pattern = Pattern.compile("(.*):\\s+(\\d+).kB");
|
||||||
|
try{
|
||||||
|
String[] lines = Files.readString(ff.toPath()).split("\n");
|
||||||
|
for (String line : lines) {
|
||||||
|
Matcher m = pattern.matcher(line);
|
||||||
|
if (m.find()){
|
||||||
|
String key = m.group(1);
|
||||||
|
int value = Integer.parseInt(m.group(2));
|
||||||
|
switch (key){
|
||||||
|
case "MemTotal":
|
||||||
|
result.totalKB = value;
|
||||||
|
break;
|
||||||
|
case "MemAvailable":
|
||||||
|
result.availableKB = value;
|
||||||
|
break;
|
||||||
|
case "SwapTotal":
|
||||||
|
result.swapTotalKB = value;
|
||||||
|
break;
|
||||||
|
case "SwapFree":
|
||||||
|
result.swapFreeKB = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
result.usedKB = result.totalKB - result.availableKB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main/java/Web/AudioFilesInfo.java
Normal file
9
src/main/java/Web/AudioFilesInfo.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package Web;
|
||||||
|
|
||||||
|
public class AudioFilesInfo {
|
||||||
|
public String preset1;
|
||||||
|
public String preset2;
|
||||||
|
public String preset3;
|
||||||
|
public String preset4;
|
||||||
|
public String preset5;
|
||||||
|
}
|
||||||
@@ -3,12 +3,14 @@ package Web;
|
|||||||
import Other.SomeCodes;
|
import Other.SomeCodes;
|
||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
import io.javalin.http.UploadedFile;
|
import io.javalin.http.UploadedFile;
|
||||||
|
import io.javalin.util.FileUtil;
|
||||||
import io.javalin.util.JavalinException;
|
import io.javalin.util.JavalinException;
|
||||||
import io.javalin.websocket.*;
|
import io.javalin.websocket.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.util.List;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -20,20 +22,24 @@ import static io.javalin.apibuilder.ApiBuilder.*;
|
|||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class WebServer {
|
public class WebServer {
|
||||||
|
private @Getter @Setter String webusername;
|
||||||
|
private @Getter @Setter String webpassword;
|
||||||
private final Javalin app;
|
private final Javalin app;
|
||||||
private final Set<WsContext> connectedWebsocketClients = ConcurrentHashMap.newKeySet();
|
private final Set<WsContext> connectedWebsocketClients = ConcurrentHashMap.newKeySet();
|
||||||
public WebServer(WebsocketEvent event, String webusername, String webpassword){
|
public WebServer(WebsocketEvent event, String webusername, String webpassword){
|
||||||
|
this.webusername = webusername;
|
||||||
|
this.webpassword = webpassword;
|
||||||
app = Javalin.create(config -> {
|
app = Javalin.create(config -> {
|
||||||
config.staticFiles.add("/html");
|
config.staticFiles.add("/html");
|
||||||
config.router.apiBuilder(()-> path("setting", () ->{
|
config.router.apiBuilder(()-> path("setting", () ->{
|
||||||
get(ctx -> ctx.json(SettingInfo.getInstance()));
|
get(ctx -> ctx.json(SettingInfo.getInstance()));
|
||||||
path("audiofile",()-> post(ctx -> {
|
path("audiofile",()-> post(ctx -> {
|
||||||
Logger.info("api /setting/audiofile");
|
Logger.info("api /setting/audiofile");
|
||||||
String audiofile1 = ctx.formParam("1");
|
String audiofile1 = ctx.formParam("preset1");
|
||||||
String audiofile2 = ctx.formParam("2");
|
String audiofile2 = ctx.formParam("preset2");
|
||||||
String audiofile3 = ctx.formParam("3");
|
String audiofile3 = ctx.formParam("preset3");
|
||||||
String audiofile4 = ctx.formParam("4");
|
String audiofile4 = ctx.formParam("preset4");
|
||||||
String audiofile5 = ctx.formParam("5");
|
String audiofile5 = ctx.formParam("preset5");
|
||||||
Logger.info("audiofile1: {}", audiofile1);
|
Logger.info("audiofile1: {}", audiofile1);
|
||||||
Logger.info("audiofile2: {}", audiofile2);
|
Logger.info("audiofile2: {}", audiofile2);
|
||||||
Logger.info("audiofile3: {}", audiofile3);
|
Logger.info("audiofile3: {}", audiofile3);
|
||||||
@@ -41,41 +47,59 @@ public class WebServer {
|
|||||||
Logger.info("audiofile5: {}", audiofile5);
|
Logger.info("audiofile5: {}", audiofile5);
|
||||||
|
|
||||||
Properties prop = SomeCodes.LoadProperties("config.properties");
|
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||||
prop.setProperty("audiofile1", audiofile1!=null?audiofile1:"");
|
prop.setProperty("AudioFile01", audiofile1!=null?audiofile1:"");
|
||||||
prop.setProperty("audiofile2", audiofile2!=null?audiofile2:"");
|
prop.setProperty("AudioFile02", audiofile2!=null?audiofile2:"");
|
||||||
prop.setProperty("audiofile3", audiofile3!=null?audiofile3:"");
|
prop.setProperty("AudioFile03", audiofile3!=null?audiofile3:"");
|
||||||
prop.setProperty("audiofile4", audiofile4!=null?audiofile4:"");
|
prop.setProperty("AudioFile04", audiofile4!=null?audiofile4:"");
|
||||||
prop.setProperty("audiofile5", audiofile5!=null?audiofile5:"");
|
prop.setProperty("AudioFile05", audiofile5!=null?audiofile5:"");
|
||||||
if (SaveProperties(prop, "config.properties")){
|
if (SaveProperties(prop, "config.properties")){
|
||||||
Logger.info("audiofile saved");
|
Logger.info("audiofile saved");
|
||||||
ctx.status(200);
|
ctx.status(200);
|
||||||
} else {
|
} else {
|
||||||
Logger.error("Failed to save audiofile");
|
Logger.error("Failed to save audiofile");
|
||||||
ctx.status(400);
|
ctx.status(400);
|
||||||
|
ctx.result("Failed to save audiofile");
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
path("uploadaudiofile", ()-> post(ctx -> {
|
path("uploadaudiofile", ()-> post(ctx -> {
|
||||||
UploadedFile file = ctx.uploadedFile("file");
|
List<UploadedFile> uploadedFileList = ctx.uploadedFiles();
|
||||||
if (file!=null){
|
int size = uploadedFileList.size();
|
||||||
try {
|
if (size>0){
|
||||||
Path targetsave = audioPath.resolve(file.filename());
|
uploadedFileList.forEach(ff ->{
|
||||||
Files.copy(file.content(), targetsave);
|
String targetsave = audioPath.resolve(ff.filename()).toString();
|
||||||
Logger.info("Uploaded file: {}, size: {} saved at {}", file.filename(),file.size(), targetsave);
|
FileUtil.streamToFile(ff.content(), targetsave);
|
||||||
} catch (Exception e){
|
Logger.info("Uploaded file: {}", targetsave);
|
||||||
Logger.error("Failed to save uploaded file: {}, Message: {}", file.filename(), e.getMessage());
|
});
|
||||||
}
|
ctx.status(200);
|
||||||
|
ctx.result("UploadedFiles: "+size);
|
||||||
|
} else {
|
||||||
|
ctx.status(400);
|
||||||
|
ctx.result("No file uploaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}));
|
}));
|
||||||
path("weblogin", ()-> post(ctx -> {
|
path("weblogin", ()-> post(ctx -> {
|
||||||
String username = ctx.formParam("username");
|
String username = ctx.formParam("username");
|
||||||
String password = ctx.formParam("password");
|
String password = ctx.formParam("password");
|
||||||
|
Logger.info("api /setting/weblogin");
|
||||||
|
Logger.info("username: {}", username);
|
||||||
|
Logger.info("password: {}", password);
|
||||||
|
|
||||||
Properties prop = SomeCodes.LoadProperties("config.properties");
|
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||||
prop.setProperty("WebUsername", ValidString(username)?username:"admin");
|
prop.setProperty("WebUsername", ValidString(username)?username:"admin");
|
||||||
prop.setProperty("WebPassword", ValidString(password)?password:"bandara");
|
prop.setProperty("WebPassword", ValidString(password)?password:"bandara");
|
||||||
if (SaveProperties(prop, "config.properties")){
|
if (SaveProperties(prop, "config.properties")){
|
||||||
ctx.status(200);
|
Logger.info("weblogin saved");
|
||||||
|
|
||||||
|
//ctx.status(200);
|
||||||
|
this.webusername = username;
|
||||||
|
this.webpassword = password;
|
||||||
|
ctx.redirect("/logout");
|
||||||
} else {
|
} else {
|
||||||
|
Logger.error("Failed to save weblogin");
|
||||||
ctx.status(400);
|
ctx.status(400);
|
||||||
|
ctx.result("Failed to save weblogin");
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
path("camera",()-> post(ctx -> {
|
path("camera",()-> post(ctx -> {
|
||||||
@@ -83,6 +107,11 @@ public class WebServer {
|
|||||||
String camera_port = ctx.formParam("port");
|
String camera_port = ctx.formParam("port");
|
||||||
String camera_username = ctx.formParam("username");
|
String camera_username = ctx.formParam("username");
|
||||||
String camera_password = ctx.formParam("password");
|
String camera_password = ctx.formParam("password");
|
||||||
|
Logger.info("api /setting/camera");
|
||||||
|
Logger.info("camera_ip: {}", camera_ip);
|
||||||
|
Logger.info("camera_port: {}", camera_port);
|
||||||
|
Logger.info("camera_username: {}", camera_username);
|
||||||
|
Logger.info("camera_password: {}", camera_password);
|
||||||
|
|
||||||
Properties prop = SomeCodes.LoadProperties("config.properties");
|
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||||
prop.setProperty("Camera_ip", ValidString(camera_ip)?camera_ip:"192.168.0.4");
|
prop.setProperty("Camera_ip", ValidString(camera_ip)?camera_ip:"192.168.0.4");
|
||||||
@@ -90,9 +119,13 @@ public class WebServer {
|
|||||||
prop.setProperty("Camera_user", ValidString(camera_username)?camera_username:"root");
|
prop.setProperty("Camera_user", ValidString(camera_username)?camera_username:"root");
|
||||||
prop.setProperty("Camera_password", ValidString(camera_password)?camera_password:"password");
|
prop.setProperty("Camera_password", ValidString(camera_password)?camera_password:"password");
|
||||||
if (SaveProperties(prop, "config.properties")){
|
if (SaveProperties(prop, "config.properties")){
|
||||||
|
Logger.info("IP camera setting saved");
|
||||||
ctx.status(200);
|
ctx.status(200);
|
||||||
|
if (event!=null) event.NewCameraConfiguration();
|
||||||
} else {
|
} else {
|
||||||
|
Logger.error("Failed to save IP camera setting");
|
||||||
ctx.status(400);
|
ctx.status(400);
|
||||||
|
ctx.result("Failed to save IP camera setting");
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -103,7 +136,7 @@ public class WebServer {
|
|||||||
if (ctx.sessionAttribute("username")==null) {
|
if (ctx.sessionAttribute("username")==null) {
|
||||||
// belum login
|
// belum login
|
||||||
ctx.redirect("/login.html");
|
ctx.redirect("/login.html");
|
||||||
} else if (Objects.equals(ctx.sessionAttribute("username"), webusername)){
|
} else if (Objects.equals(ctx.sessionAttribute("username"), this.webusername)){
|
||||||
// sudah login
|
// sudah login
|
||||||
ctx.redirect("/index.html");
|
ctx.redirect("/index.html");
|
||||||
} else {
|
} else {
|
||||||
@@ -127,11 +160,12 @@ public class WebServer {
|
|||||||
app.post("/login", ctx ->{
|
app.post("/login", ctx ->{
|
||||||
String username = ctx.formParam("username");
|
String username = ctx.formParam("username");
|
||||||
String password = ctx.formParam("password");
|
String password = ctx.formParam("password");
|
||||||
if (Objects.equals(username, webusername) && Objects.equals(password, webpassword)){
|
if (Objects.equals(username, this.webusername) && Objects.equals(password, this.webpassword)){
|
||||||
ctx.sessionAttribute("username", username);
|
ctx.sessionAttribute("username", username);
|
||||||
ctx.redirect("/index.html");
|
ctx.redirect("/index.html");
|
||||||
} else {
|
} else {
|
||||||
ctx.redirect("/login.html?error=Invalid username or password");
|
ctx.status(400);
|
||||||
|
ctx.redirect("/login.html");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -151,9 +185,12 @@ public class WebServer {
|
|||||||
if (event!=null) {
|
if (event!=null) {
|
||||||
WebsocketReply reply = event.onWebsocketCommand(command);
|
WebsocketReply reply = event.onWebsocketCommand(command);
|
||||||
if (reply!=null) ctx.sendAsClass(reply, WebsocketReply.class);
|
if (reply!=null) ctx.sendAsClass(reply, WebsocketReply.class);
|
||||||
|
//if (reply!=null) SendtoAll(reply);
|
||||||
}
|
}
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
Logger.error("Failed to parse WebSocketCommand message: {}", e.getMessage());
|
Logger.error("Failed to parse WebSocketCommand message: {}", e.getMessage());
|
||||||
|
ctx.closeSession();
|
||||||
|
connectedWebsocketClients.remove(ctx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -196,13 +233,13 @@ public class WebServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WsConnectHandler connectws = ws ->{
|
WsConnectHandler connectws = ws ->{
|
||||||
Logger.info("WebSocket connected from {}", ws.host());
|
Logger.info("WebSocket connected from {}", ws.sessionId());
|
||||||
//ws.headerMap().forEach((key, value) -> Logger.info("HeaderMap {}: {}", key, value));
|
//ws.headerMap().forEach((key, value) -> Logger.info("HeaderMap {}: {}", key, value));
|
||||||
connectedWebsocketClients.add(ws);
|
connectedWebsocketClients.add(ws);
|
||||||
};
|
};
|
||||||
|
|
||||||
WsCloseHandler closews = ws ->{
|
WsCloseHandler closews = ws ->{
|
||||||
Logger.info("WebSocket closed from {}, code {}, reason {}", ws.host(), ws.status(), ws.reason());
|
Logger.info("WebSocket closed from {}, code {}, reason {}", ws.sessionId(), ws.status(), ws.reason());
|
||||||
connectedWebsocketClients.remove(ws);
|
connectedWebsocketClients.remove(ws);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ package Web;
|
|||||||
public interface WebsocketEvent {
|
public interface WebsocketEvent {
|
||||||
String onMessage(String message);
|
String onMessage(String message);
|
||||||
WebsocketReply onWebsocketCommand(WebsocketCommand command);
|
WebsocketReply onWebsocketCommand(WebsocketCommand command);
|
||||||
|
void NewCameraConfiguration();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,23 @@ package id.co.gtc;
|
|||||||
|
|
||||||
import Audio.AudioFileProperties;
|
import Audio.AudioFileProperties;
|
||||||
import Audio.AudioPlayer;
|
import Audio.AudioPlayer;
|
||||||
|
import Audio.Bass;
|
||||||
import Audio.PlaybackEvent;
|
import Audio.PlaybackEvent;
|
||||||
import Camera.PanTiltController;
|
import Camera.PanTiltController;
|
||||||
import Camera.RtspGrabber;
|
import Camera.RtspGrabber;
|
||||||
import Camera.VapixProtocol;
|
import Camera.VapixProtocol;
|
||||||
import Other.SomeCodes;
|
import Other.SomeCodes;
|
||||||
import Web.WebServer;
|
import SBC.ProcessorStatus;
|
||||||
import Web.WebsocketCommand;
|
import SBC.RamInformation;
|
||||||
import Web.WebsocketEvent;
|
import SBC.SystemInformation;
|
||||||
import Web.WebsocketReply;
|
import Web.*;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import org.bytedeco.opencv.global.opencv_core;
|
import org.bytedeco.opencv.global.opencv_core;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.*;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import static Other.SomeCodes.*;
|
import static Other.SomeCodes.*;
|
||||||
|
|
||||||
@@ -28,6 +29,11 @@ public class Main {
|
|||||||
private static PanTiltController panTiltController;
|
private static PanTiltController panTiltController;
|
||||||
private static AudioFileProperties audioFileProperties;
|
private static AudioFileProperties audioFileProperties;
|
||||||
private static VapixProtocol vapixProtocol;
|
private static VapixProtocol vapixProtocol;
|
||||||
|
private static Timer timer;
|
||||||
|
private static int cpuTemperature;
|
||||||
|
private static RamInformation ramInformation;
|
||||||
|
private static ProcessorStatus[] previousCpuInfo;
|
||||||
|
private static final Map<String, Integer> cpuUsage = new HashMap<>();
|
||||||
|
|
||||||
// Application start from here
|
// Application start from here
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@@ -37,8 +43,11 @@ public class Main {
|
|||||||
if (rtspGrabber!=null) rtspGrabber.Stop();
|
if (rtspGrabber!=null) rtspGrabber.Stop();
|
||||||
if (panTiltController!=null) panTiltController.Close();
|
if (panTiltController!=null) panTiltController.Close();
|
||||||
if (vapixProtocol!=null) vapixProtocol.Close();
|
if (vapixProtocol!=null) vapixProtocol.Close();
|
||||||
|
if (timer!=null) timer.cancel();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
init_system_monitoring();
|
||||||
|
|
||||||
init_properties();
|
init_properties();
|
||||||
init_audiofiles();
|
init_audiofiles();
|
||||||
|
|
||||||
@@ -49,6 +58,29 @@ public class Main {
|
|||||||
init_Vapix();
|
init_Vapix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void init_system_monitoring(){
|
||||||
|
TimerTask tt = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
cpuTemperature = SystemInformation.getCPUTemperature();
|
||||||
|
ramInformation = SystemInformation.getRAMInformation();
|
||||||
|
ProcessorStatus[] cpuinfo = SystemInformation.getProcStat();
|
||||||
|
if (cpuinfo.length>0){
|
||||||
|
if (previousCpuInfo==null || !Objects.equals(previousCpuInfo.length, cpuinfo.length)){
|
||||||
|
previousCpuInfo = cpuinfo;
|
||||||
|
} else {
|
||||||
|
for(int ii=0;ii<previousCpuInfo.length;ii++){
|
||||||
|
cpuUsage.put(cpuinfo[ii].name, cpuinfo[ii].cpu_usage(previousCpuInfo[ii]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
timer = new Timer();
|
||||||
|
timer.scheduleAtFixedRate(tt, 1000, 5000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static void init_properties(){
|
private static void init_properties(){
|
||||||
if (ExtractResource("/tinylog.properties", currentDirectory)==null) Logger.error("Failed to extract tinylog.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("/config.properties", currentDirectory)==null) Logger.error("Failed to extract config.properties");
|
||||||
@@ -73,21 +105,24 @@ public class Main {
|
|||||||
String username = config.getProperty("Camera_user");
|
String username = config.getProperty("Camera_user");
|
||||||
String password = config.getProperty("Camera_password");
|
String password = config.getProperty("Camera_password");
|
||||||
if (ValidString(ip)){
|
if (ValidString(ip)){
|
||||||
if (ValidInteger(port)){
|
if (ValidPortNumber(port)){
|
||||||
if (ValidString(username)){
|
if (ValidString(username)){
|
||||||
if (ValidString(password)){
|
if (ValidString(password)){
|
||||||
vapixProtocol = new VapixProtocol(ip, Integer.parseInt(port), username, password);
|
if (IpIsReachable(ip)){
|
||||||
Logger.info("Camera Product Number: "+vapixProtocol.GetProductNumber());
|
Logger.info("Camera IP is reachable");
|
||||||
Logger.info("Camera Serial Number: "+vapixProtocol.GetSerialNumber());
|
vapixProtocol = new VapixProtocol(ip, Integer.parseInt(port), username, password);
|
||||||
if (vapixProtocol.PTZEnabled()){
|
Logger.info("Camera Product Number: "+vapixProtocol.GetProductNumber());
|
||||||
Logger.info("PTZ Enabled");
|
Logger.info("Camera Serial Number: "+vapixProtocol.GetSerialNumber());
|
||||||
} else Logger.error("PTZ Disabled");
|
if (vapixProtocol.PTZEnabled()){
|
||||||
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
|
Logger.info("PTZ Enabled");
|
||||||
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
|
} else Logger.error("PTZ Disabled");
|
||||||
} else Logger.error("Invalid Camera Password");
|
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
|
||||||
} else Logger.error("Invalid Camera Username");
|
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
|
||||||
} else Logger.error("Invalid Camera Port");
|
} else Logger.error("Camera IP is not reachable");
|
||||||
} else Logger.error("Invalid Camera IP");
|
} else Logger.error("Camera Password is not valid string");
|
||||||
|
} else Logger.error("Camera Username is not valid string");
|
||||||
|
} else Logger.error("Camera Port is not valid");
|
||||||
|
} else Logger.error( "Camera IP is not valid string");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void init_pantiltcontroller() {
|
private static void init_pantiltcontroller() {
|
||||||
@@ -112,22 +147,32 @@ public class Main {
|
|||||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||||
String targetip = config.getProperty("Camera_ip");
|
String targetip = config.getProperty("Camera_ip");
|
||||||
String rtsppath = config.getProperty("Camera_Rtsp_path");
|
String rtsppath = config.getProperty("Camera_Rtsp_path");
|
||||||
|
rtspGrabber = null;
|
||||||
if (ValidString(targetip)){
|
if (ValidString(targetip)){
|
||||||
if (ValidString(rtsppath)){
|
if (ValidString(rtsppath)){
|
||||||
rtspGrabber = new RtspGrabber(targetip, rtsppath);
|
if (IpIsReachable(targetip)){
|
||||||
|
Logger.info("Camera IP is reachable");
|
||||||
|
rtspGrabber = new RtspGrabber(targetip, rtsppath);
|
||||||
rtspGrabber.Start(true, 1920, 1080);
|
rtspGrabber.Start(true, 1920, 1080);
|
||||||
} else Logger.error("Invalid Camera Path");
|
} else Logger.error("Camera IP is not reachable");
|
||||||
} else Logger.error("Invalid Camera IP");
|
} else Logger.error("Camera Path is not valid string");
|
||||||
|
} else Logger.error("Camera IP is not valid string");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void init_audio() {
|
private static void init_audio() {
|
||||||
audioPlayer = new AudioPlayer();
|
audioPlayer = new AudioPlayer();
|
||||||
audioPlayer.DetectOutputDevices();
|
audioPlayer.DetectOutputDevices();
|
||||||
audioPlayer.OpenDevice(1,48000);
|
int devid = audioPlayer.FindDeviceIDWithName("USB");
|
||||||
audioPlayer.setMasterVolume(100);
|
if (devid<1) devid = audioPlayer.FindDeviceIDWithName("Speakers");
|
||||||
audioPlayer.setPlaybackvolume(100);
|
|
||||||
|
if (devid>0){
|
||||||
|
Bass.BASS_DEVICEINFO info = audioPlayer.GetDeviceInfo(devid);
|
||||||
|
if (audioPlayer.OpenDevice(devid,48000)){
|
||||||
|
audioPlayer.setMasterVolume(100);
|
||||||
|
audioPlayer.setPlaybackvolume(100);
|
||||||
|
Logger.info("Audio Device ID={} opened : {}", devid, info.name);
|
||||||
|
} else Logger.error("Failed to open Audio Device ID={}", devid);
|
||||||
|
} else Logger.error("USB Audio Device not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
static PlaybackEvent pe = new PlaybackEvent() {
|
static PlaybackEvent pe = new PlaybackEvent() {
|
||||||
@@ -217,6 +262,7 @@ public class Main {
|
|||||||
audioFileProperties = afp;
|
audioFileProperties = afp;
|
||||||
audioPlayer.PlayAudioFile(afp, true, pe);
|
audioPlayer.PlayAudioFile(afp, true, pe);
|
||||||
return new WebsocketReply("PLAY AUDIO", afp.filename);
|
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", "Failed to open audio file "+filename);
|
||||||
} else return new WebsocketReply("PLAY AUDIO", "Audio file not found : "+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", String.format("AudioFile with ID %02d not found", id));
|
||||||
@@ -252,20 +298,64 @@ public class Main {
|
|||||||
case "GET BASE64":
|
case "GET BASE64":
|
||||||
if (rtspGrabber!=null){
|
if (rtspGrabber!=null){
|
||||||
if (Objects.equals(command.data,"HQ"))
|
if (Objects.equals(command.data,"HQ"))
|
||||||
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastHQBase64(), String.format("Streaming at %dx%d", rtspGrabber.getHQWidth(), rtspGrabber.getHQHeight()));
|
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
|
||||||
else
|
else
|
||||||
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastLQBase64(), String.format("Streaming at %dx%d", rtspGrabber.getLQWidth(), rtspGrabber.getLQHeight()));
|
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
|
||||||
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||||
case "GET RESOLUTION":
|
case "GET RESOLUTION":
|
||||||
if (vapixProtocol!=null){
|
if (vapixProtocol!=null){
|
||||||
int[] res = vapixProtocol.GetCurrentResolution(1);
|
int[] res = vapixProtocol.GetCurrentResolution(1);
|
||||||
return new WebsocketReply("GET RESOLUTION", String.format("%dx%d", res[0], res[1]));
|
return new WebsocketReply("GET RESOLUTION", String.format("%dx%d", res[0], res[1]));
|
||||||
} else return new WebsocketReply("GET RESOLUTION", "VapixProtocol not initialized");
|
} else return new WebsocketReply("GET RESOLUTION", "VapixProtocol not initialized");
|
||||||
|
case "GET AUDIOFILES":
|
||||||
|
AudioFilesInfo afi = new AudioFilesInfo();
|
||||||
|
afi.preset1 = GetConfigAudioFile(1);
|
||||||
|
afi.preset2 = GetConfigAudioFile(2);
|
||||||
|
afi.preset3 = GetConfigAudioFile(3);
|
||||||
|
afi.preset4 = GetConfigAudioFile(4);
|
||||||
|
afi.preset5 = GetConfigAudioFile(5);
|
||||||
|
return new WebsocketReply("GET AUDIOFILES", gson.toJson(afi));
|
||||||
|
case "GET SYSTEM INFO":
|
||||||
|
JsonObject data = new JsonObject();
|
||||||
|
data.addProperty("cpu_temperature", String.valueOf(cpuTemperature));
|
||||||
|
if (ramInformation!=null) {
|
||||||
|
data.addProperty("ram_usage", String.format("%.1f", ramInformation.RamUsagePercentage()));
|
||||||
|
}
|
||||||
|
if (!cpuUsage.isEmpty()) {
|
||||||
|
for(String key : cpuUsage.keySet()){
|
||||||
|
data.addProperty(key, String.valueOf(cpuUsage.get(key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new WebsocketReply("GET SYSTEM INFO", data.toString());
|
||||||
default:
|
default:
|
||||||
return new WebsocketReply("UNKNOWN COMMAND", command.command);
|
return new WebsocketReply("UNKNOWN COMMAND", command.command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void NewCameraConfiguration() {
|
||||||
|
Logger.info("New Camera Configuration detected");
|
||||||
|
Properties prop = SomeCodes.LoadProperties("config.properties");
|
||||||
|
String camera_ip = prop.getProperty("Camera_ip");
|
||||||
|
String camera_port = prop.getProperty("Camera_port");
|
||||||
|
String camera_user = prop.getProperty("Camera_user");
|
||||||
|
String camera_password = prop.getProperty("Camera_password");
|
||||||
|
String camera_rtsp_path = prop.getProperty("Camera_Rtsp_path");
|
||||||
|
Logger.info("Camera Ip: "+camera_ip);
|
||||||
|
Logger.info("Camera Port: "+camera_port);
|
||||||
|
Logger.info("Camera User: "+camera_user);
|
||||||
|
Logger.info("Camera Password: "+camera_password);
|
||||||
|
Logger.info("Camera Rtsp Path: "+camera_rtsp_path);
|
||||||
|
|
||||||
|
if (rtspGrabber!=null) rtspGrabber.Stop();
|
||||||
|
init_rtspgrabber();
|
||||||
|
Logger.info("RtspGrabber recreated");
|
||||||
|
|
||||||
|
if (vapixProtocol!=null) vapixProtocol.Close();
|
||||||
|
init_Vapix();
|
||||||
|
Logger.info("VapixProtocol recreated");
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static void init_webserver() {
|
private static void init_webserver() {
|
||||||
|
|||||||
Reference in New Issue
Block a user