Kirim ke Bandara 27/02/2025
This commit is contained in:
@@ -10,7 +10,7 @@ AudioFile03 = pinkNoiseWav.wav
|
||||
AudioFile04 = 04.mp3
|
||||
AudioFile05 = 05.mp3
|
||||
AudioVolumeOutput = 100
|
||||
SerialPort = /dev/ttyAMA0
|
||||
SerialPort = /dev/ttyTHS1
|
||||
SerialBaudRate = 9600
|
||||
PanTiltID = 1
|
||||
WebUsername = admin
|
||||
|
||||
@@ -692,11 +692,12 @@ function process_command(dx){
|
||||
* @type {{cpu_temperature: string, ram_usage: string, cpu: string, cpu0: string, cpu1: string, cpu2: string, cpu3: string}} systeminfo
|
||||
*/
|
||||
let systeminfo = JSON.parse(dx.data);
|
||||
//console.log(systeminfo);
|
||||
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} %`);
|
||||
if (systeminfo.end0_TX && systeminfo.end0_TX.length>0) $('#ethernet_TX').html(systeminfo.end0_TX);
|
||||
if (systeminfo.end0_RX && systeminfo.end0_RX.length>0) $('#ethernet_RX').html(systeminfo.end0_RX);
|
||||
if (systeminfo.enP8p1s0_TX && systeminfo.enP8p1s0_TX.length>0) $('#ethernet_TX').html(systeminfo.enP8p1s0_TX);
|
||||
if (systeminfo.enP8p1s0_RX && systeminfo.enP8p1s0_RX.length>0) $('#ethernet_RX').html(systeminfo.enP8p1s0_RX);
|
||||
break;
|
||||
case "GET AUDIOFILES":
|
||||
//console.log("Get Audio Files: "+dx.data);
|
||||
|
||||
@@ -12,7 +12,7 @@ Camera_port=80
|
||||
Camera_user=root
|
||||
PanTiltID=1
|
||||
SerialBaudRate=9600
|
||||
SerialPort=/dev/ttyAMA0
|
||||
SerialPort=/dev/ttyTHS1
|
||||
WebHost=0.0.0.0
|
||||
WebPassword=bandara
|
||||
WebPort=8080
|
||||
|
||||
Binary file not shown.
Binary file not shown.
16
pom.xml
16
pom.xml
@@ -57,12 +57,13 @@
|
||||
<classifier>linux-arm64</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>tensorrt</artifactId>
|
||||
<version>8.6-1.5.10</version>
|
||||
<classifier>linux-arm64</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>cuda</artifactId>
|
||||
@@ -70,6 +71,19 @@
|
||||
<classifier>linux-arm64</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>1.5.11</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>1.5.11</version>
|
||||
<classifier>linux-arm64</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.corundumstudio.socketio</groupId>
|
||||
|
||||
@@ -1,14 +1,33 @@
|
||||
package Audio;
|
||||
|
||||
|
||||
public class AudioFileProperties {
|
||||
public final int handle;
|
||||
public final String filename;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class AudioFileProperties extends Structure {
|
||||
public int handle;
|
||||
public String filename;
|
||||
public long Length;
|
||||
public double duration;
|
||||
public AudioFileProperties(int handle, String filename){
|
||||
|
||||
public AudioFileProperties(Pointer p){
|
||||
super(p);
|
||||
read();
|
||||
}
|
||||
|
||||
public AudioFileProperties(int handle, String filename, long length, double duration){
|
||||
this.handle = handle;
|
||||
this.filename = filename;
|
||||
this.Length = length;
|
||||
this.duration = duration;
|
||||
write();
|
||||
}
|
||||
|
||||
protected List<String> getFieldOrder() {
|
||||
return Arrays.asList("handle", "filename", "Length", "duration");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -193,9 +193,9 @@ public class AudioPlayer {
|
||||
int handle = bass.BASS_StreamCreateFile(false, ff.getAbsolutePath(), 0, 0,0);
|
||||
if (handle!=0){
|
||||
Logger.info("Audio file {} opened successfully", ff.getName());
|
||||
AudioFileProperties prop = new AudioFileProperties(handle, ff.getName());
|
||||
prop.Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE);
|
||||
prop.duration = bass.BASS_ChannelBytes2Seconds(handle, prop.Length);
|
||||
long Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE);
|
||||
double duration = bass.BASS_ChannelBytes2Seconds(handle, Length);
|
||||
AudioFileProperties prop = new AudioFileProperties(handle, ff.getName(), Length, duration);
|
||||
return prop;
|
||||
} else Logger.error("Failed to open audio file {}, Error Code {}", ff.getAbsolutePath(), bass.BASS_ErrorGetCode());
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
@@ -217,8 +217,39 @@ public class AudioPlayer {
|
||||
} else Logger.info("Audio file {} closed successfully", prop.filename);
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PlaybackEvent playbackEvent = null;
|
||||
|
||||
Bass.SYNCPROC endproc = (handle, channel, data, user)->{
|
||||
if (user!=null){
|
||||
AudioFileProperties ap = new AudioFileProperties(user);
|
||||
if (playbackEvent!=null){
|
||||
playbackEvent.onPlaybackFinished(ap);
|
||||
} else Logger.warn("endproc playbackEvent is null");
|
||||
} else Logger.warn("endproc user is null");
|
||||
|
||||
};
|
||||
|
||||
Bass.SYNCPROC freeproc = (handle, channel, data, user)->{
|
||||
if (user!=null){
|
||||
AudioFileProperties ap = new AudioFileProperties(user);
|
||||
if (playbackEvent!=null){
|
||||
playbackEvent.onPlaybackFinished(ap);
|
||||
} else Logger.warn("freeproc playbackEvent is null");
|
||||
} else Logger.warn("freeproc user is null");
|
||||
};
|
||||
|
||||
Bass.SYNCPROC failproc = (handle, channel, data, user)->{
|
||||
if (user!=null){
|
||||
AudioFileProperties ap = new AudioFileProperties(user);
|
||||
if (playbackEvent!=null){
|
||||
playbackEvent.onPlaybackFailure(ap, "Device Failure");
|
||||
} else Logger.warn("failproc playbackEvent is null");
|
||||
} else Logger.warn("failproc user is null");
|
||||
};
|
||||
|
||||
/**
|
||||
* Play Audio File
|
||||
* @param prop AudioFileProperties object to play
|
||||
@@ -226,23 +257,23 @@ public class AudioPlayer {
|
||||
* @param event PlaybackEvent object to handle playback event
|
||||
*/
|
||||
public void PlayAudioFile(AudioFileProperties prop, boolean looping, PlaybackEvent event){
|
||||
this.playbackEvent = null;
|
||||
if (inited){
|
||||
if (prop!=null){
|
||||
if (bass.BASS_ChannelStart(prop.handle)){
|
||||
this.playbackEvent = event;
|
||||
playbackhandle = prop.handle;
|
||||
// SyncProcValue spv = new SyncProcValue(prop);
|
||||
// spv.write();
|
||||
bass.BASS_ChannelSetAttribute(prop.handle, Bass.BASS_ATTRIB_VOL, playbackvolume);
|
||||
if (looping) bass.BASS_ChannelFlags(prop.handle, Bass.BASS_SAMPLE_LOOP, Bass.BASS_SAMPLE_LOOP);
|
||||
if (event!=null) event.onPlaybackStart(prop);
|
||||
int devfailsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_DEV_FAIL,0, (handle, channel, data, user)->{
|
||||
if (event!=null) event.onPlaybackFailure(prop, "Device Failure");
|
||||
}, null);
|
||||
int devfailsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_DEV_FAIL,0, failproc, prop.getPointer());
|
||||
if (devfailsync==0) Logger.error("Failed to set Device Failure Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
int endsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_END, 0, (handle, channel, data, user)->{
|
||||
if (looping) {
|
||||
if (event!=null) event.onPlaybackLooped(prop);
|
||||
} else if (event!=null) event.onPlaybackFinished(prop);
|
||||
}, null);
|
||||
int endsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_END , 0, endproc, prop.getPointer());
|
||||
if (endsync==0) Logger.error("Failed to set End Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
int freesync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_FREE , 0, freeproc, prop.getPointer());
|
||||
if (freesync==0) Logger.error("Failed to set Free Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
} else {
|
||||
if (event!=null) event.onPlaybackFailure(prop, String.format("Failed to play audio file %s, Error Code %d", prop.filename, bass.BASS_ErrorGetCode()));
|
||||
}
|
||||
@@ -254,4 +285,23 @@ public class AudioPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
// static class SyncProcValue extends Structure{
|
||||
// public AudioFileProperties ap;
|
||||
// public SyncProcValue(AudioFileProperties ap){
|
||||
// this.ap = ap;
|
||||
// }
|
||||
//
|
||||
// public SyncProcValue(Pointer p){
|
||||
// super(p);
|
||||
// read();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected List<String> getFieldOrder() {
|
||||
// return Arrays.asList("ap");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package Audio;
|
||||
|
||||
import com.sun.jna.*;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface Bass extends Library {
|
||||
|
||||
323
src/main/java/Audio/MultiUSBAudioPlayer.java
Normal file
323
src/main/java/Audio/MultiUSBAudioPlayer.java
Normal file
@@ -0,0 +1,323 @@
|
||||
package Audio;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MultiUSBAudioPlayer {
|
||||
private final Bass bass;
|
||||
private int[] deviceid;
|
||||
@Getter
|
||||
private boolean inited = false;
|
||||
|
||||
PlaybackHandlewithId[] playbackhandle;
|
||||
float playbackvolume = 1.0f;
|
||||
List<BassDeviceInfoWithId> playbackdevices = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create Multi USB Audio Player
|
||||
*/
|
||||
public MultiUSBAudioPlayer() {
|
||||
bass = Bass.Instance;
|
||||
Logger.info("Bass Version = {}", Integer.toHexString(bass.BASS_GetVersion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload Multi USB Audio Player
|
||||
*/
|
||||
public void Unload(){
|
||||
if (inited){
|
||||
if (deviceid!=null && deviceid.length>0){
|
||||
for(int id: deviceid){
|
||||
Logger.info("Freeing Device {}", id);
|
||||
bass.BASS_SetDevice(id);
|
||||
bass.BASS_Free();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
deviceid = null;
|
||||
inited = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect Output Devices
|
||||
*/
|
||||
public void DetectOutputDevices(){
|
||||
Logger.info("Detecting Output Devices...");
|
||||
int ii = 1;
|
||||
playbackdevices.clear();
|
||||
while (true){
|
||||
Bass.BASS_DEVICEINFO info = new Bass.BASS_DEVICEINFO();
|
||||
if (bass.BASS_GetDeviceInfo(ii, info)){
|
||||
//Logger.info("Device {} = {}, flags = {}", ii, info.name, Integer.toHexString(info.flags));
|
||||
playbackdevices.add(new BassDeviceInfoWithId(ii, info));
|
||||
ii++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find playback devices with name
|
||||
* @param name specific name
|
||||
* @return array of device id
|
||||
*/
|
||||
public int[] FindDeviceIDWithName(String name){
|
||||
if (playbackdevices!=null && !playbackdevices.isEmpty()){
|
||||
List<Integer> result = new ArrayList<>();
|
||||
for(BassDeviceInfoWithId dev : playbackdevices){
|
||||
if (dev.info.name.toLowerCase().contains(name.toLowerCase())){
|
||||
result.add(dev.id);
|
||||
}
|
||||
}
|
||||
return result.stream().mapToInt(i->i).toArray();
|
||||
}
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Open Devices
|
||||
* @param device list of device id
|
||||
* @param freq frequency
|
||||
* @return true if any device is successfully initialized
|
||||
*/
|
||||
public boolean OpenDevice(int[] device, int freq){
|
||||
if (device!=null && device.length>0){
|
||||
int flag = Bass.BASS_DEVICE_REINIT | Bass.BASS_DEVICE_16BITS | Bass.BASS_DEVICE_MONO | Bass.BASS_DEVICE_FREQ;
|
||||
|
||||
List<Integer> validdevice = new ArrayList<>();
|
||||
for(int i : device){
|
||||
boolean result = bass.BASS_Init(i, freq, flag);
|
||||
if (result){
|
||||
Logger.info("Device {} initialized", i);
|
||||
validdevice.add(i);
|
||||
inited = true;
|
||||
} else {
|
||||
Logger.error("Failed to initialize device {}", i);
|
||||
}
|
||||
}
|
||||
deviceid = validdevice.stream().mapToInt(i->i).toArray();
|
||||
return inited;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public void setMasterVolume(int value){
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
if (inited){
|
||||
if (deviceid!=null && deviceid.length>0){
|
||||
for(int id : deviceid){
|
||||
bass.BASS_SetDevice(id);
|
||||
if (!bass.BASS_SetVolume(value/100.0f)){
|
||||
Logger.error("Failed to set Master Volume to {}, Error Code {}", value, bass.BASS_ErrorGetCode());
|
||||
} else Logger.info("Master Volume set to {}", value);
|
||||
}
|
||||
} else Logger.error("No device initialized");
|
||||
} else Logger.info("MultiUSBAudioPlayer not initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Playback Volume
|
||||
* is the volume of the currently playing audio file
|
||||
* @return 0 - 100
|
||||
*/
|
||||
public int getPlaybackvolume(){
|
||||
if (playbackvolume<0)
|
||||
return 0;
|
||||
else if (playbackvolume>1.0f)
|
||||
return 100;
|
||||
else
|
||||
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){
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
playbackvolume = value/100.0f;
|
||||
if (playbackhandle!=null && playbackhandle.length>0){
|
||||
for(PlaybackHandlewithId ph : playbackhandle){
|
||||
if (ph.handle.handle!=0){
|
||||
bass.BASS_SetDevice(ph.id);
|
||||
bass.BASS_ChannelSetAttribute(ph.handle.handle, Bass.BASS_ATTRIB_VOL, playbackvolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float lastplaybackvolume = 1.0f;
|
||||
|
||||
/**
|
||||
* Set Playback Volume to 0
|
||||
*/
|
||||
public void Mute(){
|
||||
lastplaybackvolume = playbackvolume;
|
||||
setPlaybackvolume(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Playback Volume to last volume before Mute
|
||||
*/
|
||||
public void Unmute(){
|
||||
setPlaybackvolume((int)lastplaybackvolume*100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open Audio File
|
||||
* @param ff audio file name to open
|
||||
* @return AudioFileProperties object or null if failed
|
||||
*/
|
||||
public PlaybackHandlewithId[] OpenAudioFile(File ff){
|
||||
if (inited){
|
||||
AudioFileProperties prop;
|
||||
List<PlaybackHandlewithId> phs = new ArrayList<>();
|
||||
for(int id: deviceid){
|
||||
bass.BASS_SetDevice(id);
|
||||
int handle = bass.BASS_StreamCreateFile(false, ff.getAbsolutePath(), 0, 0,0);
|
||||
if (handle!=0){
|
||||
long Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE);
|
||||
double duration = bass.BASS_ChannelBytes2Seconds(handle, Length);
|
||||
prop = new AudioFileProperties(handle, ff.getName(), Length, duration);
|
||||
PlaybackHandlewithId ph = new PlaybackHandlewithId(id, prop);
|
||||
phs.add(ph);
|
||||
}
|
||||
}
|
||||
if (!phs.isEmpty()){
|
||||
playbackhandle = phs.toArray(new PlaybackHandlewithId[0]);
|
||||
Logger.info("Audio file {} opened successfully", ff.getName());
|
||||
return playbackhandle;
|
||||
} else {
|
||||
Logger.error("Failed to open audio file {}, Error Code {}", ff.getName(), bass.BASS_ErrorGetCode());
|
||||
}
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
return new PlaybackHandlewithId[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Audio File
|
||||
* @param prop AudioFileProperties object to close
|
||||
*/
|
||||
public void CloseAudioFile(PlaybackHandlewithId[] prop) {
|
||||
if (inited) {
|
||||
if (prop != null && prop.length>0) {
|
||||
for(PlaybackHandlewithId ph : prop){
|
||||
if (ph.handle.handle!=0){
|
||||
bass.BASS_SetDevice(ph.id);
|
||||
if (!bass.BASS_ChannelFree(ph.handle.handle)){
|
||||
Logger.error("Failed to close audio file {}, Error Code {}", ph.handle.filename, bass.BASS_ErrorGetCode());
|
||||
} else {
|
||||
Logger.info("Audio file {} closed successfully", ph.handle.filename);
|
||||
}
|
||||
bass.BASS_Stop();
|
||||
|
||||
}
|
||||
}
|
||||
} else Logger.info("AudioPlayer not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
PlaybackEvent playbackEvent = null;
|
||||
|
||||
Bass.SYNCPROC endproc = (handle, channel, data, user)->{
|
||||
if (user!=null){
|
||||
AudioFileProperties ap = new AudioFileProperties(user);
|
||||
if (playbackEvent!=null){
|
||||
playbackEvent.onPlaybackFinished(ap);
|
||||
} else Logger.warn("endproc playbackEvent is null");
|
||||
} else Logger.warn("endproc user is null");
|
||||
|
||||
};
|
||||
|
||||
Bass.SYNCPROC freeproc = (handle, channel, data, user)->{
|
||||
if (user!=null){
|
||||
AudioFileProperties ap = new AudioFileProperties(user);
|
||||
if (playbackEvent!=null){
|
||||
playbackEvent.onPlaybackFinished(ap);
|
||||
} else Logger.warn("freeproc playbackEvent is null");
|
||||
} else Logger.warn("freeproc user is null");
|
||||
};
|
||||
|
||||
Bass.SYNCPROC failproc = (handle, channel, data, user)->{
|
||||
if (user!=null){
|
||||
AudioFileProperties ap = new AudioFileProperties(user);
|
||||
if (playbackEvent!=null){
|
||||
playbackEvent.onPlaybackFailure(ap, "Device Failure");
|
||||
} else Logger.warn("failproc playbackEvent is null");
|
||||
} else Logger.warn("failproc user is null");
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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(PlaybackHandlewithId[] prop, boolean looping, PlaybackEvent event){
|
||||
if (inited){
|
||||
if (prop!=null && prop.length>0){
|
||||
this.playbackEvent = event;
|
||||
for(PlaybackHandlewithId ph : prop){
|
||||
if (ph.handle.handle!=0){
|
||||
bass.BASS_SetDevice(ph.id);
|
||||
bass.BASS_Start();
|
||||
if (bass.BASS_ChannelStart(ph.handle.handle)) {
|
||||
|
||||
bass.BASS_ChannelSetAttribute(ph.handle.handle, Bass.BASS_ATTRIB_VOL, playbackvolume);
|
||||
if (looping) bass.BASS_ChannelFlags(ph.handle.handle, Bass.BASS_SAMPLE_LOOP, Bass.BASS_SAMPLE_LOOP);
|
||||
if (event != null) event.onPlaybackStart(ph.handle);
|
||||
int devfailsync = bass.BASS_ChannelSetSync(ph.handle.handle, Bass.BASS_SYNC_DEV_FAIL, 0, failproc, ph.handle.getPointer());
|
||||
if (devfailsync == 0) Logger.error("Failed to set Device Failure Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
int endsync = bass.BASS_ChannelSetSync(ph.handle.handle, Bass.BASS_SYNC_END, 0, endproc, ph.handle.getPointer());
|
||||
if (endsync == 0) Logger.error("Failed to set End Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
int freesync = bass.BASS_ChannelSetSync(ph.handle.handle, Bass.BASS_SYNC_FREE, 0, freeproc, ph.handle.getPointer());
|
||||
if (freesync == 0) Logger.error("Failed to set Free Sync, Error Code {}", bass.BASS_ErrorGetCode());
|
||||
} else {
|
||||
if (event != null){
|
||||
event.onPlaybackFailure(ph.handle, String.format("Failed to play audio file %s, Error Code %d", ph.handle.filename, bass.BASS_ErrorGetCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (event!=null) event.onPlaybackFailure(null, "AudioFileProperties is null");
|
||||
}
|
||||
} else {
|
||||
if (event!=null) event.onPlaybackFailure(null, "AudioPlayer not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlaybackHandlewithId{
|
||||
public final int id;
|
||||
public final AudioFileProperties handle;
|
||||
public PlaybackHandlewithId(int id, AudioFileProperties handle){
|
||||
this.id = id;
|
||||
this.handle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
static class BassDeviceInfoWithId{
|
||||
public final int id;
|
||||
public final Bass.BASS_DEVICEINFO info;
|
||||
public BassDeviceInfoWithId(int id, Bass.BASS_DEVICEINFO info){
|
||||
this.id = id;
|
||||
this.info = info;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ public class GrabbingTask implements Runnable {
|
||||
// for FPS calculation
|
||||
private int intendedFps = 10;
|
||||
|
||||
private final boolean useYolo;
|
||||
private final YoloDetector yolo;
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@@ -89,11 +90,12 @@ public class GrabbingTask implements Runnable {
|
||||
|
||||
|
||||
|
||||
public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber, int fps) {
|
||||
public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber, int fps, boolean useYolo) {
|
||||
this.isGrabbing = isGrabbing;
|
||||
this.grabber = grabber;
|
||||
if (fps>0) intendedFps = fps;
|
||||
yolo = new YoloDetector();
|
||||
this.useYolo = useYolo;
|
||||
if (useYolo) yolo = new YoloDetector(); else yolo = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,37 +118,52 @@ public class GrabbingTask implements Runnable {
|
||||
Frame resizedFrame = SomeCodes.CoreMatConverter.convert(resized);
|
||||
updateLQFrame(resizedFrame);
|
||||
updateLQBase64(SomeCodes.MatToBase64(resized));
|
||||
} else System.out.println("processFrame resized size is 0");
|
||||
DetectYolo(mat);
|
||||
|
||||
if (useYolo){
|
||||
DetectYolo(resized);
|
||||
}
|
||||
} else Logger.error("processFrame resized size is 0");
|
||||
resized.release();
|
||||
} else System.out.println("processFrame Mat size is 0");
|
||||
} else Logger.error("processFrame Mat size is 0");
|
||||
mat.release();
|
||||
} catch (Exception e){
|
||||
Logger.error("Error processing frame: "+e.getMessage());
|
||||
if (SomeCodes.ValidString(e.getMessage())) {
|
||||
if (!e.getMessage().startsWith("unknown exception")) {
|
||||
Logger.error("Error processing frame: "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
System.out.println("processFrame have null frame");
|
||||
Logger.warn("processFrame have null frame");
|
||||
updateMessage("processFrame have null frame");
|
||||
}
|
||||
}
|
||||
|
||||
private void DetectYolo(Mat mat){
|
||||
if (mat!=null && mat.cols()>0 && mat.rows()>0){
|
||||
//System.out.println("DetectYolo mat cols = "+mat.cols()+", rows = "+mat.rows());
|
||||
try{
|
||||
Mat[] processed = yolo.Detect(mat);
|
||||
Mat yolomat = yolo.Process(mat, processed[0], processed[1]);
|
||||
Frame yoloFrame = SomeCodes.CoreMatConverter.convert(yolomat);
|
||||
updateYoloFrame(yoloFrame);
|
||||
updateYoloBase64(SomeCodes.MatToBase64(yolomat));
|
||||
if (yolo!=null){
|
||||
if (mat!=null && mat.cols()>0 && mat.rows()>0){
|
||||
try {
|
||||
// [0] = predict, [1] = mask
|
||||
Mat[] processed = yolo.Detect(mat);
|
||||
// gambar dalam bentuk Mat
|
||||
Mat yolomat = yolo.Process(mat, processed[0], processed[1]);
|
||||
// convert jadi frame
|
||||
Frame yoloFrame = SomeCodes.MatToFrame(yolomat);
|
||||
updateYoloFrame(yoloFrame);
|
||||
updateYoloBase64(SomeCodes.MatToBase64(yolomat));
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error("error processing YOLO, Message : " + e.getMessage());
|
||||
updateYoloFrame(null);
|
||||
updateYoloBase64("");
|
||||
}
|
||||
|
||||
} else Logger.error("DetectYolo mat is null");
|
||||
}
|
||||
|
||||
} catch (Exception e){
|
||||
System.out.println("error processing YOLO, Message : "+e.getMessage());
|
||||
updateYoloFrame(null);
|
||||
updateYoloBase64("");
|
||||
}
|
||||
} else System.out.println("DetectYolo mat is null");
|
||||
|
||||
}
|
||||
|
||||
@@ -173,11 +190,14 @@ public class GrabbingTask implements Runnable {
|
||||
Thread.yield();
|
||||
Frame frame = grabber.grab();
|
||||
if (framecount<Integer.MAX_VALUE) framecount++; else framecount = 0;
|
||||
//processFrame(frame);
|
||||
// no need to skip frames, just process all frames
|
||||
if (framecount % skippedframes == 0) {
|
||||
processFrame(frame);
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error grabbing frame: "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -70,11 +70,10 @@ public class PanTiltController {
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
if (isOpen()) {
|
||||
Main.Max485Direction(true);
|
||||
int written = serialPort.writeBytes(command, command.length);
|
||||
serialPort.writeBytes(command, command.length);
|
||||
Main.Max485Direction(false);
|
||||
Main.Blink_LedPanTilt();
|
||||
System.out.println("Stop Movement written : "+written);
|
||||
} else System.out.println("Stop Movement failed, serial port not open");
|
||||
} else Logger.warn("Stop Movement failed, serial port not open");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,11 +89,10 @@ public class PanTiltController {
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
if (isOpen()) {
|
||||
Main.Max485Direction(true);
|
||||
int written = serialPort.writeBytes(command, command.length);
|
||||
serialPort.writeBytes(command, command.length);
|
||||
Main.Max485Direction(false);
|
||||
Main.Blink_LedPanTilt();
|
||||
System.out.println("Pan Left written : "+written);
|
||||
} else System.out.println("Pan Left failed, serial port not open");
|
||||
} else Logger.warn("Pan Left failed, serial port not open");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,11 +108,10 @@ public class PanTiltController {
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
if (isOpen()) {
|
||||
Main.Max485Direction(true);
|
||||
int written = serialPort.writeBytes(command, command.length);
|
||||
serialPort.writeBytes(command, command.length);
|
||||
Main.Max485Direction(false);
|
||||
Main.Blink_LedPanTilt();
|
||||
System.out.println("Pan Right written : "+written);
|
||||
} else System.out.println("Pan Right failed, serial port not open");
|
||||
} else Logger.warn("Pan Right failed, serial port not open");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,11 +127,10 @@ public class PanTiltController {
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
if (isOpen()) {
|
||||
Main.Max485Direction(true);
|
||||
int written = serialPort.writeBytes(command, command.length);
|
||||
serialPort.writeBytes(command, command.length);
|
||||
Main.Max485Direction(false);
|
||||
Main.Blink_LedPanTilt();
|
||||
System.out.println("Tilt Up written : "+written);
|
||||
} else System.out.println("Tilt Up failed, serial port not open");
|
||||
} else Logger.warn("Tilt Up failed, serial port not open");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,11 +146,10 @@ public class PanTiltController {
|
||||
command[0] = (byte) 0xFF; // add synchronization byte
|
||||
if (isOpen()) {
|
||||
Main.Max485Direction(true);
|
||||
int written = serialPort.writeBytes(command, command.length);
|
||||
serialPort.writeBytes(command, command.length);
|
||||
Main.Max485Direction(false);
|
||||
Main.Blink_LedPanTilt();
|
||||
System.out.println("Tilt Down written : "+written);
|
||||
} else System.out.println("Tilt Down failed, serial port not open");
|
||||
} else Logger.warn("Tilt Down failed, serial port not open");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,16 +26,12 @@ public class RtspGrabber {
|
||||
private @Getter int HQHeight = 0;
|
||||
private @Getter int LQWidth = 0;
|
||||
private @Getter int LQHeight = 0;
|
||||
private final boolean useYolo;
|
||||
private GrabbingTask grabbingTask;
|
||||
|
||||
public RtspGrabber(String ip, String path) {
|
||||
int cudacount = opencv_core.getCudaEnabledDeviceCount();
|
||||
if (cudacount>0){
|
||||
Logger.info("CUDA enabled devices found: " + cudacount);
|
||||
opencv_core.printCudaDeviceInfo(0);
|
||||
} else {
|
||||
Logger.info("No CUDA enabled devices found");
|
||||
}
|
||||
public RtspGrabber(String ip, String path, boolean useYolo) {
|
||||
this.useYolo = useYolo;
|
||||
|
||||
this.rtspUrl = "rtsp://" + ip + path;
|
||||
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
||||
}
|
||||
@@ -146,7 +142,7 @@ public class RtspGrabber {
|
||||
|
||||
@NotNull
|
||||
private GrabbingTask getGrabbingTask() {
|
||||
GrabbingTask tt = new GrabbingTask(isGrabbing, grabber,10);
|
||||
GrabbingTask tt = new GrabbingTask(isGrabbing, grabber,10, useYolo);
|
||||
tt.setOnMessageUpdate(Logger::info);
|
||||
tt.setOnHQFrameUpdate(value -> {
|
||||
if (value!=null){
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.opencv.core.*;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.dnn.Net;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -26,18 +27,20 @@ public class YoloDetector {
|
||||
// Non-maximum suppression threshold
|
||||
private final float nms_threshold = 0.4f;
|
||||
|
||||
|
||||
public YoloDetector() {
|
||||
NetLoaded = false;
|
||||
net = null;
|
||||
classes = null;
|
||||
String onnxfile = SomeCodes.ExtractResource("/yolov8n.onnx", SomeCodes.currentDirectory);
|
||||
String onnxfile = SomeCodes.ExtractResource("/yolo11n.onnx", SomeCodes.currentDirectory);
|
||||
String namesfile = SomeCodes.ExtractResource("/coco.names", SomeCodes.currentDirectory);
|
||||
if (SomeCodes.ValidFile(onnxfile)){
|
||||
if (SomeCodes.ValidFile(namesfile)){
|
||||
net = Dnn.readNetFromONNX(onnxfile);
|
||||
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||
//net.setPreferableBackend(Dnn.DNN_BACKEND_INFERENCE_ENGINE);
|
||||
net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
|
||||
|
||||
//net.setPreferableTarget(Dnn.DNN_TARGET_NPU);
|
||||
|
||||
classes = new ArrayList<>();
|
||||
if (namesfile!=null){
|
||||
@@ -47,72 +50,87 @@ public class YoloDetector {
|
||||
classes.add(line);
|
||||
}
|
||||
} catch (Exception e){
|
||||
System.out.println("Error: reading names file");
|
||||
Logger.error("reading names file, Exception : ",e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!net.empty()){
|
||||
if (!classes.isEmpty()){
|
||||
NetLoaded = true;
|
||||
} else System.out.println("Error: names file is empty");
|
||||
} else System.out.println("Error: net is empty");
|
||||
} else System.out.println("Error: names file not found");
|
||||
} else System.out.println("Error: onnx file not found");
|
||||
} else Logger.error("names file is empty");
|
||||
} else Logger.error("net is empty");
|
||||
} else Logger.error("names file not found");
|
||||
} else Logger.error("onnx file not found");
|
||||
}
|
||||
|
||||
// Source : https://blog.csdn.net/taoli188/article/details/134720614
|
||||
public Mat[] Detect(Mat frame){
|
||||
if (NetLoaded){
|
||||
Size inputSize = new Size(640, 640);
|
||||
Scalar mean = new Scalar(0, 0, 0, 0);
|
||||
float scaleFactor = 1.0f/255.0f;
|
||||
boolean swapRB = true;
|
||||
boolean crop = true;
|
||||
try{
|
||||
if (NetLoaded){
|
||||
Size inputSize = new Size(640, 640);
|
||||
Scalar mean = new Scalar(0, 0, 0, 0);
|
||||
float scaleFactor = 1.0f/255.0f;
|
||||
boolean swapRB = true;
|
||||
boolean crop = false;
|
||||
|
||||
Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize, mean , swapRB, crop, CV_32F);
|
||||
//Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize);
|
||||
net.setInput(blob);
|
||||
Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize, mean , swapRB, crop, CV_32F);
|
||||
//Mat blob = Dnn.blobFromImage(frame, scaleFactor, inputSize);
|
||||
net.setInput(blob);
|
||||
|
||||
Mat predict = net.forward();
|
||||
Mat mask = predict.reshape(0,1).reshape(0, predict.size(1));
|
||||
Mat predict = net.forward();
|
||||
Mat mask = predict.reshape(0,1).reshape(0, predict.size(1));
|
||||
|
||||
return new Mat[]{predict,mask};
|
||||
} else {
|
||||
System.out.println("Error: Net not loaded");
|
||||
return new Mat[]{predict,mask};
|
||||
} else {
|
||||
Logger.error("Net not loaded");
|
||||
return new Mat[0];
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error detecting: "+e.getMessage());
|
||||
return new Mat[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Mat Process(Mat frame, Mat predict, Mat mask){
|
||||
double width = frame.cols() / 640.0;
|
||||
double height = frame.rows() / 640.0;
|
||||
Rect2d[] rect2d = new Rect2d[mask.cols()];
|
||||
float[] scoref = new float[mask.cols()];
|
||||
int[] classid = new int[mask.cols()];
|
||||
try{
|
||||
double width = frame.cols() / 640.0;
|
||||
double height = frame.rows() / 640.0;
|
||||
Rect2d[] rect2d = new Rect2d[mask.cols()];
|
||||
float[] scoref = new float[mask.cols()];
|
||||
int[] classid = new int[mask.cols()];
|
||||
|
||||
for(int i=0;i<mask.cols();i++){
|
||||
double[] x = mask.col(i).get(0, 0);
|
||||
double[] y = mask.col(i).get(1, 0);
|
||||
double[] w = mask.col(i).get(2, 0);
|
||||
double[] h = mask.col(i).get(3, 0);
|
||||
rect2d[i] = new Rect2d((x[0]-w[0]/2)*width, (y[0]-h[0]/2)*height, w[0]*width, h[0]*height);
|
||||
Mat score = mask.col(i).submat(4, predict.size(1)-1,0,1) ;
|
||||
Core.MinMaxLocResult mm = Core.minMaxLoc(score);
|
||||
scoref[i] = (float)mm.maxVal;
|
||||
classid[i] = (int)mm.maxLoc.y;
|
||||
for(int i=0;i<mask.cols();i++){
|
||||
double[] x = mask.col(i).get(0, 0);
|
||||
double[] y = mask.col(i).get(1, 0);
|
||||
double[] w = mask.col(i).get(2, 0);
|
||||
double[] h = mask.col(i).get(3, 0);
|
||||
rect2d[i] = new Rect2d((x[0]-w[0]/2)*width, (y[0]-h[0]/2)*height, w[0]*width, h[0]*height);
|
||||
Mat score = mask.col(i).submat(4, predict.size(1)-1,0,1) ;
|
||||
Core.MinMaxLocResult mm = Core.minMaxLoc(score);
|
||||
scoref[i] = (float)mm.maxVal;
|
||||
classid[i] = (int)mm.maxLoc.y;
|
||||
}
|
||||
|
||||
MatOfRect2d bboxes = new MatOfRect2d(rect2d);
|
||||
MatOfFloat scores = new MatOfFloat(scoref);
|
||||
MatOfInt indices = new MatOfInt();
|
||||
Dnn.NMSBoxes(bboxes, scores, confidence_threshold, nms_threshold, indices);
|
||||
|
||||
if (indices!=null && !indices.empty()){
|
||||
int[] idx = indices.toArray();
|
||||
for(int ii : idx){
|
||||
Rect rr = new Rect(rect2d[ii].tl(), rect2d[ii].size());
|
||||
Imgproc.rectangle(frame, rr, new Scalar(0, 255, 0), 2);
|
||||
Imgproc.putText(frame, classes.get(classid[ii])+" "+String.format("%.2f", scoref[ii]), rr.tl(), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(0, 0, 255));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e){
|
||||
Logger.error("Error processing detection: "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
MatOfRect2d bboxes = new MatOfRect2d(rect2d);
|
||||
MatOfFloat scores = new MatOfFloat(scoref);
|
||||
MatOfInt indices = new MatOfInt();
|
||||
Dnn.NMSBoxes(bboxes, scores, confidence_threshold, nms_threshold, indices);
|
||||
|
||||
int[] idx = indices.toArray();
|
||||
for(int ii : idx){
|
||||
//System.out.println("Detected ["+ii+"] ClassID: "+classid[ii]+" Label: "+classes.get(classid[ii])+" Confidence: "+scoref[ii]);
|
||||
Rect rr = new Rect(rect2d[ii].tl(), rect2d[ii].size());
|
||||
Imgproc.rectangle(frame, rr, new Scalar(0, 255, 0), 2);
|
||||
Imgproc.putText(frame, classes.get(classid[ii])+" "+String.format("%.2f", scoref[ii]), rr.tl(), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(0, 0, 255));
|
||||
}
|
||||
|
||||
|
||||
return frame;
|
||||
@@ -158,7 +176,7 @@ public class YoloDetector {
|
||||
int classId = classIds.get(idx);
|
||||
float confidence = confidences.get(idx);
|
||||
String label = classes.get(classId);
|
||||
System.out.println("Detect ["+idx+"] ClassID: "+classId+" Label: "+label+" Confidence: "+confidence);
|
||||
Logger.info("Detect ["+idx+"] ClassID: "+classId+" Label: "+label+" Confidence: "+confidence);
|
||||
|
||||
Imgproc.rectangle(frame, box, new Scalar(0, 255, 0), 2);
|
||||
String text = label + " " + String.format("%.2f", confidence);
|
||||
@@ -170,7 +188,7 @@ public class YoloDetector {
|
||||
Imgproc.putText(frame, text, new Point(box.x, box.y),
|
||||
Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0));
|
||||
}
|
||||
} else System.out.println("No detections");
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.bytedeco.javacpp.Loader;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||
import org.bytedeco.opencv.global.opencv_core;
|
||||
import org.bytedeco.opencv.global.opencv_imgcodecs;
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.*;
|
||||
import org.bytedeco.opencv.opencv_java;
|
||||
@@ -111,6 +110,15 @@ public class SomeCodes {
|
||||
}
|
||||
}
|
||||
|
||||
public static String IntArrayToString(int[] id){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i : id){
|
||||
if (!sb.isEmpty()) sb.append(",");
|
||||
sb.append(i);
|
||||
}
|
||||
return "["+ sb +"]";
|
||||
}
|
||||
|
||||
public static boolean ValidPortNumber(int port){
|
||||
return port>0 && port<65536;
|
||||
}
|
||||
@@ -124,46 +132,33 @@ public class SomeCodes {
|
||||
}
|
||||
}
|
||||
|
||||
public static String MatToBase64(Mat mat){
|
||||
if (mat!=null){
|
||||
if (mat.cols()>0 && mat.rows()>0){
|
||||
byte[] mob = new byte[mat.cols()*mat.rows()*mat.channels()];
|
||||
opencv_imgcodecs.imencode(".jpg", mat, mob);
|
||||
return base64encoder.encodeToString(mob);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String MatToBase64(org.opencv.core.Mat mat){
|
||||
if (mat!=null){
|
||||
if (mat.cols()>0 && mat.rows()>0){
|
||||
MatOfByte mob = new MatOfByte();
|
||||
Imgcodecs.imencode(".jpg", mat, mob);
|
||||
String base64 = base64encoder.encodeToString(mob.toArray());
|
||||
mob.release();
|
||||
return base64;
|
||||
try{
|
||||
MatOfByte mob = new MatOfByte();
|
||||
Imgcodecs.imencode(".jpg", mat, mob);
|
||||
String base64 = base64encoder.encodeToString(mob.toArray());
|
||||
mob.release();
|
||||
return base64;
|
||||
} catch (Exception e){
|
||||
Logger.error("Error converting Mat to Base64: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// Function ini pakai opencv, bukan javacv, jadi perlu Loader.load(opencv_java.class) di awal
|
||||
// lebih optimal untuk konversi frame ke base64
|
||||
public static String FrameToBase64(Frame frame){
|
||||
if (frame!=null && frame.imageWidth>0 && frame.imageHeight>0){
|
||||
org.opencv.core.Mat converted = CoreMatConverter.convert(frame);
|
||||
if (converted!=null && converted.cols()>0 && converted.rows()>0){
|
||||
//System.out.println("FrameToBase64 use converted Mat, cols: "+converted.cols()+", rows: "+converted.rows());
|
||||
return MatToBase64(converted);
|
||||
}
|
||||
Mat xx = CoreMatConverter.convertToMat(frame);
|
||||
if (xx!=null && xx.cols()>0 && xx.rows()>0){
|
||||
//System.out.println("FrameToBase64 use xx Mat, cols: "+xx.cols()+", rows: "+xx.rows());
|
||||
return MatToBase64(xx);
|
||||
public static Frame MatToFrame(org.opencv.core.Mat mat){
|
||||
if (mat!=null && mat.cols()>0 && mat.rows()>0){
|
||||
try{
|
||||
return CoreMatConverter.convert(mat);
|
||||
} catch (Exception e){
|
||||
Logger.error("Error converting Mat to Frame: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
package SBC;
|
||||
|
||||
/**
|
||||
* Source : <a href="https://jetsonhacks.com/nvidia-jetson-agx-orin-gpio-header-pinout/">...</a>
|
||||
* Source : <a href="https://jetsonhacks.com/nvidia-jetson-orin-nano-gpio-header-pinout/">...</a>
|
||||
*/
|
||||
public enum JetsonOrinPins {
|
||||
Pin07(7,"MCLK05",106),
|
||||
Pin07(7,"AUDIO_MCLK",144),
|
||||
Pin11(11,"UART1_RTS",112),
|
||||
Pin12(12,"I2S2_CLK",50),
|
||||
Pin13(13,"GPIO32",108),
|
||||
Pin15(15,"GPIO27",85),
|
||||
Pin16(16,"GPIO8",9),
|
||||
Pin18(18,"GPIO35",43),
|
||||
Pin19(19,"SPI1_MOSI",135),
|
||||
Pin21(21,"SPI1_MISO",134),
|
||||
Pin22(22,"GPIO17",96),
|
||||
Pin23(23,"SPI1_SCK",133),
|
||||
Pin24(24,"SPI1_CS0",136),
|
||||
Pin25(25,"SPI1_CS1",137),
|
||||
Pin29(29,"CAN0_RX",1),
|
||||
Pin31(31,"CAN0_TX",0),
|
||||
Pin32(32,"GPIO9",8),
|
||||
Pin33(33,"CAN1_TX",2),
|
||||
Pin35(35,"I2S_FS",53),
|
||||
Pin12(12,"I2S0_SCLK",50),
|
||||
Pin13(13,"SPI1_SCK",122),
|
||||
Pin15(15,"GPIO12",85),
|
||||
Pin16(16,"SPI1_CS1",126),
|
||||
Pin18(18,"SPI1_CS0",125),
|
||||
Pin19(19,"SPI0_MOSI",135),
|
||||
Pin21(21,"SPI0_MISO",134),
|
||||
Pin22(22,"SPI1_MISO",123),
|
||||
Pin23(23,"SPI0_SCK",133),
|
||||
Pin24(24,"SPI0_CS0",136),
|
||||
Pin25(26,"SPI0_CS1",137),
|
||||
Pin29(29,"GPIO01",105),
|
||||
Pin31(31,"GPIO11",106),
|
||||
Pin32(32,"GPIO07",41),
|
||||
Pin33(33,"GPIO13",43),
|
||||
Pin35(35,"I2S0_FS",53),
|
||||
Pin36(36,"UART1_CTS",113),
|
||||
Pin37(37,"CAN1_RX",3),
|
||||
Pin38(38,"I2S_SDIN",52),
|
||||
Pin40(40,"I2S_SDOUT",51);
|
||||
Pin37(37,"SPI1_MOSI",124),
|
||||
Pin38(38,"I2S0_SDIN",52),
|
||||
Pin40(40,"I2S0_SDOUT",51);
|
||||
public final int pin;
|
||||
public final String name;
|
||||
public final int gpionumber;
|
||||
|
||||
20
src/main/java/SBC/LibGpioD.java
Normal file
20
src/main/java/SBC/LibGpioD.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package SBC;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
public interface LibGpioD extends Library {
|
||||
String CHIP_NAME = "/dev/gpiochip0"; // First GPIO chip
|
||||
LibGpioD Instance = Native.load("gpiod", LibGpioD.class);
|
||||
|
||||
Pointer gpiod_chip_open(String chipname);
|
||||
void gpiod_chip_close(Pointer chip);
|
||||
|
||||
Pointer gpiod_line_get(Pointer chip, int offset);
|
||||
int gpiod_line_request_output(Pointer line, String consumer, int default_val);
|
||||
int gpiod_line_request_input(Pointer line, String consumer);
|
||||
int gpiod_line_set_value(Pointer line, int value);
|
||||
int gpiod_line_get_value(Pointer line);
|
||||
void gpiod_line_release(Pointer line);
|
||||
}
|
||||
@@ -2,10 +2,11 @@ package SBC;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class PCF8574 extends I2C_Device{
|
||||
|
||||
private byte data = 0x00;
|
||||
private Byte data = 0;
|
||||
private final @Getter String[] pinNames = new String[8];
|
||||
|
||||
/**
|
||||
@@ -92,8 +93,10 @@ public class PCF8574 extends I2C_Device{
|
||||
public boolean SetPin(int pin){
|
||||
if (pin<0 || pin>7) return false;
|
||||
if (super.isOpened()){
|
||||
byte temp = (byte) (data | (1<<pin));
|
||||
return super.WriteBytes(new byte[]{temp})>0;
|
||||
synchronized (data){
|
||||
data = (byte) (data | (1<<pin));
|
||||
return super.WriteBytes(new byte[]{data})>0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -120,8 +123,10 @@ public class PCF8574 extends I2C_Device{
|
||||
public boolean ClearPin(int pin){
|
||||
if (pin<0 || pin>7) return false;
|
||||
if (super.isOpened()){
|
||||
byte temp = (byte) (data & ~(1<<pin));
|
||||
return super.WriteBytes(new byte[]{temp})>0;
|
||||
synchronized (data){
|
||||
data = (byte) (data & ~(1<<pin));
|
||||
return super.WriteBytes(new byte[]{data})>0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class SystemInformation {
|
||||
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+)");
|
||||
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){
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package id.co.gtc;
|
||||
|
||||
import Audio.AudioFileProperties;
|
||||
import Audio.AudioPlayer;
|
||||
import Audio.Bass;
|
||||
import Audio.PlaybackEvent;
|
||||
import Audio.*;
|
||||
import Camera.PanTiltController;
|
||||
import Camera.RtspGrabber;
|
||||
import Camera.VapixProtocol;
|
||||
@@ -12,6 +9,7 @@ import SBC.*;
|
||||
import Web.*;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.sun.jna.Platform;
|
||||
import com.sun.jna.Pointer;
|
||||
import org.bytedeco.opencv.global.opencv_core;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
@@ -24,11 +22,20 @@ import java.util.concurrent.Executors;
|
||||
import static Other.SomeCodes.*;
|
||||
|
||||
public class Main {
|
||||
//change parameter ini untuk single audio output atau multi audio output
|
||||
private static final boolean use_multiusb_audio = true;
|
||||
private static MultiUSBAudioPlayer multiUSBAudioPlayer;
|
||||
private static MultiUSBAudioPlayer.PlaybackHandlewithId[] playbackHandles;
|
||||
private static AudioPlayer audioPlayer;
|
||||
private static WebServer webServer;
|
||||
private static RtspGrabber rtspGrabber;
|
||||
private static PanTiltController panTiltController;
|
||||
private static AudioFileProperties audioFileProperties;
|
||||
|
||||
private static WebServer webServer;
|
||||
|
||||
//change parameter ini untuk menggunakan Yolo atau tidak
|
||||
private static final boolean use_Yolo = true;
|
||||
private static RtspGrabber rtspGrabber;
|
||||
|
||||
private static PanTiltController panTiltController;
|
||||
private static VapixProtocol vapixProtocol;
|
||||
private static Timer timer;
|
||||
private static int cpuTemperature;
|
||||
@@ -52,7 +59,11 @@ public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("jna.debug_load", "false");
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
if (audioPlayer!=null) audioPlayer.Unload();
|
||||
if (use_multiusb_audio) {
|
||||
if (multiUSBAudioPlayer != null) multiUSBAudioPlayer.Unload();
|
||||
} else {
|
||||
if (audioPlayer != null) audioPlayer.Unload();
|
||||
}
|
||||
if (webServer!=null) webServer.Stop();
|
||||
if (rtspGrabber!=null) rtspGrabber.Stop();
|
||||
if (panTiltController!=null) panTiltController.Close();
|
||||
@@ -77,10 +88,11 @@ public class Main {
|
||||
if (pcf8574!=null){
|
||||
pcf8574.Close();
|
||||
}
|
||||
Logger.info("Application Stopped");
|
||||
|
||||
}));
|
||||
|
||||
System.out.println("Current Directory : "+currentDirectory);
|
||||
Logger.info("Current Directory : "+currentDirectory);
|
||||
|
||||
|
||||
//init_gpio();
|
||||
@@ -91,7 +103,13 @@ public class Main {
|
||||
init_audiofiles();
|
||||
|
||||
init_Vapix();
|
||||
init_audio();
|
||||
if (use_multiusb_audio) {
|
||||
Logger.info("Using MultiUSB Audio");
|
||||
init_multiusb_audio();
|
||||
} else {
|
||||
Logger.info("Using USB Audio");
|
||||
init_audio();
|
||||
}
|
||||
|
||||
init_pantiltcontroller();
|
||||
init_webserver();
|
||||
@@ -105,28 +123,76 @@ public class Main {
|
||||
Logger.info("I2C Bus opened");
|
||||
pcf8574 = new PCF8574(i2c_bus.getI2c_handle(), 0x27);
|
||||
if (pcf8574.Open_Slave()){
|
||||
System.out.println("PCF8574 opened");
|
||||
Logger.info("PCF8574 opened");
|
||||
pcf8574.AllOff();
|
||||
pcf8574.setPinName(0, "Amplifier Power");
|
||||
pcf8574.setPinName(1, "Led Web");
|
||||
pcf8574.setPinName(2, "Led IP Camera");
|
||||
pcf8574.setPinName(3, "Led Pan Tilt");
|
||||
pcf8574.setPinName(4, "Max485 Direction");
|
||||
// pcf8574.setPinName(0, "Amplifier Power");
|
||||
// pcf8574.setPinName(1, "Led Web");
|
||||
// pcf8574.setPinName(2, "Led IP Camera");
|
||||
// pcf8574.setPinName(3, "Led Pan Tilt");
|
||||
// pcf8574.setPinName(4, "Max485 Direction");
|
||||
gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
|
||||
|
||||
|
||||
} else {
|
||||
System.out.println("Failed to open PCF8574");
|
||||
Logger.error("Failed to open PCF8574");
|
||||
}
|
||||
} else {
|
||||
System.out.println("Failed to open I2C Bus");
|
||||
Logger.error("Failed to open I2C Bus");
|
||||
}
|
||||
} else System.out.println("PCF8574 not supported on this platform");
|
||||
} else Logger.error("PCF8574 not supported on this platform");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
// Untuk test libgpiod
|
||||
// use for jetpack 6.x
|
||||
@SuppressWarnings("unused")
|
||||
private static void init_gpio(){
|
||||
LibGpioD gpio;
|
||||
Pointer openPointer;
|
||||
// Source : https://jetsonhacks.com/nvidia-jetson-orin-nano-gpio-header-pinout/
|
||||
int gpio_MOSI = 135;
|
||||
int gpio_MISO = 134;
|
||||
if (Platform.isLinux()){
|
||||
gpio = LibGpioD.Instance;
|
||||
openPointer = gpio.gpiod_chip_open(LibGpioD.CHIP_NAME);
|
||||
if (openPointer!=null){
|
||||
Logger.info("GPIO Chip opened : {}", LibGpioD.CHIP_NAME);
|
||||
Pointer miso = gpio.gpiod_line_get(openPointer, gpio_MISO);
|
||||
if (miso!=null){
|
||||
Logger.info("GPIO Line MISO opened : {}", gpio_MISO);
|
||||
if (gpio.gpiod_line_request_input(miso, "MISO")!=0){
|
||||
Logger.error("Failed to set MISO as input");
|
||||
} else {
|
||||
Logger.info("MISO opened");
|
||||
Logger.info("MISO value : {}", gpio.gpiod_line_get_value(miso));
|
||||
}
|
||||
gpio.gpiod_line_release(miso);
|
||||
Logger.info("GPIO Line MISO released : {}", gpio_MISO);
|
||||
} else Logger.error("Failed to open GPIO Line : {}", gpio_MISO);
|
||||
Pointer mosi = gpio.gpiod_line_get(openPointer, gpio_MOSI);
|
||||
if (mosi!=null){
|
||||
Logger.info("GPIO Line MOSI opened : {}", gpio_MOSI);
|
||||
if (gpio.gpiod_line_request_output(mosi, "MOSI", 0)!=0){
|
||||
Logger.error("Failed to set MOSI as output");
|
||||
} else {
|
||||
Logger.info("MOSI opened");
|
||||
int result = gpio.gpiod_line_set_value(mosi, 1);
|
||||
if (result!=0){
|
||||
Logger.error("Failed to set MOSI value : {}", result);
|
||||
} else Logger.info("Success set MOSI value : 1");
|
||||
}
|
||||
gpio.gpiod_line_release(mosi);
|
||||
Logger.info("GPIO Line MOSI released : {}", gpio_MOSI);
|
||||
} else Logger.error("Failed to open GPIO Line : {}", gpio_MOSI);
|
||||
gpio.gpiod_chip_close(openPointer);
|
||||
Logger.info("GPIO Chip closed : {}", LibGpioD.CHIP_NAME);
|
||||
} else Logger.error("Failed to open GPIO Chip : {}", LibGpioD.CHIP_NAME);
|
||||
} else Logger.info("GPIO not supported on this platform");
|
||||
}
|
||||
|
||||
|
||||
// use for jetpack 4.x and 5.x
|
||||
@SuppressWarnings("unused")
|
||||
private static void init_gpio_sysfs(){
|
||||
if (Platform.isLinux()){
|
||||
if (GPIO.HaveGPIO()){
|
||||
gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
|
||||
@@ -141,7 +207,7 @@ public class Main {
|
||||
GPIO.SetValue(LedPanTilt,false);
|
||||
GPIO.SetValue(Max485Direction,false);
|
||||
}
|
||||
} else System.out.println("GPIO not supported on this platform");
|
||||
} else Logger.info("GPIO not supported on this platform");
|
||||
}
|
||||
|
||||
|
||||
@@ -169,11 +235,11 @@ public class Main {
|
||||
if (Max485Direction!=null){
|
||||
GPIO.SetValue(Max485Direction, isTransmit);
|
||||
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||
if (isTransmit){
|
||||
pcf8574.SetPin("Max485 Direction");
|
||||
} else {
|
||||
pcf8574.ClearPin("Max485 Direction");
|
||||
}
|
||||
// if (isTransmit){
|
||||
// pcf8574.SetPin("Max485 Direction");
|
||||
// } else {
|
||||
// pcf8574.ClearPin("Max485 Direction");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +248,7 @@ public class Main {
|
||||
if (LedPanTilt!=null){
|
||||
Blink(LedPanTilt);
|
||||
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||
Blink("Led Pan Tilt");
|
||||
Blink(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +256,7 @@ public class Main {
|
||||
if (LedWeb!=null){
|
||||
Blink(LedWeb);
|
||||
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||
Blink("Led Web");
|
||||
Blink(3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,38 +264,47 @@ public class Main {
|
||||
if (LedIpCamera!=null){
|
||||
Blink(LedIpCamera);
|
||||
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||
Blink("Led IP Camera");
|
||||
Blink(2);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AmplifierControl(boolean isON){
|
||||
if (AmplifierPower!=null){
|
||||
Logger.info("GPIO Amplifier Power : ",isON);
|
||||
GPIO.SetValue(AmplifierPower, isON);
|
||||
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||
if (isON){
|
||||
pcf8574.SetPin("Amplifier Power");
|
||||
Logger.info("PCF8574 Amplifier Power ON");
|
||||
pcf8574.SetPin(6);
|
||||
pcf8574.SetPin(5);
|
||||
pcf8574.SetPin(4);
|
||||
} else {
|
||||
pcf8574.ClearPin("Amplifier Power");
|
||||
Logger.info("PCF8574 Amplifier Power OFF");
|
||||
pcf8574.ClearPin(6);
|
||||
pcf8574.ClearPin(5);
|
||||
pcf8574.ClearPin(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Blink(String pinName){
|
||||
private static void Blink(int pin){
|
||||
if (pcf8574!=null && pcf8574.isOpened()){
|
||||
if (gpioExecutor!=null){
|
||||
gpioExecutor.submit(()->{
|
||||
pcf8574.SetPin(pinName);
|
||||
pcf8574.SetPin(pin);
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
pcf8574.ClearPin(pinName);
|
||||
pcf8574.ClearPin(pin);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void Blink(JetsonOrinPins pin){
|
||||
if (pin!=null){
|
||||
if (gpioExecutor!=null){
|
||||
@@ -322,15 +397,15 @@ public class Main {
|
||||
|
||||
private static void init_Vapix(){
|
||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||
System.out.println("Saved Configuration for Camera");
|
||||
Logger.info("Saved Configuration for Camera");
|
||||
String ip = config.getProperty("Camera_ip");
|
||||
String port = config.getProperty("Camera_port");
|
||||
String username = config.getProperty("Camera_user");
|
||||
String password = config.getProperty("Camera_password");
|
||||
System.out.println("Camera IP : "+ip);
|
||||
System.out.println("Camera Port : "+port);
|
||||
System.out.println("Camera Username : "+username);
|
||||
System.out.println("Camera Password : "+password);
|
||||
Logger.info("Camera IP : "+ip);
|
||||
Logger.info("Camera Port : "+port);
|
||||
Logger.info("Camera Username : "+username);
|
||||
Logger.info("Camera Password : "+password);
|
||||
|
||||
if (ValidString(ip)){
|
||||
if (ValidPortNumber(port)){
|
||||
@@ -356,27 +431,7 @@ public class Main {
|
||||
} else Logger.error( "Camera IP is not valid string");
|
||||
}
|
||||
|
||||
private static void test_pantiltcontroller(){
|
||||
System.out.println("Pan Tilt Controller Test");
|
||||
panTiltController.PanLeft((byte)0x20);
|
||||
System.out.println("Pan Left");
|
||||
Sleep(2000);
|
||||
panTiltController.PanRight((byte)0x20);
|
||||
System.out.println("Pan Right");
|
||||
Sleep(2000);
|
||||
panTiltController.StopMovement();
|
||||
System.out.println("Stop Movement");
|
||||
panTiltController.TiltUp((byte)0x20);
|
||||
System.out.println("Tilt Up");
|
||||
Sleep(2000);
|
||||
panTiltController.TiltDown((byte)0x20);
|
||||
System.out.println("Tilt Down");
|
||||
Sleep(2000);
|
||||
panTiltController.StopMovement();
|
||||
System.out.println("Stop Movement");
|
||||
panTiltController.GoToPreset((byte)0);
|
||||
System.out.println("Go To Preset 0");
|
||||
}
|
||||
|
||||
|
||||
private static void init_pantiltcontroller() {
|
||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||
@@ -391,7 +446,7 @@ public class Main {
|
||||
if (ValidInteger(baudrate)){
|
||||
if (ValidInteger(PanTiltID)){
|
||||
panTiltController = new PanTiltController(portname, Integer.parseInt(baudrate), Integer.parseInt(PanTiltID));
|
||||
if (panTiltController.isOpen()) test_pantiltcontroller();
|
||||
//if (panTiltController.isOpen()) test_pantiltcontroller();
|
||||
}
|
||||
} else Logger.error("Invalid PTZ Baudrate");
|
||||
} else Logger.error("Invalid PTZ Port");
|
||||
@@ -402,21 +457,42 @@ public class Main {
|
||||
// check if really activated
|
||||
useOpenCL = opencv_core.useOpenCL();
|
||||
Logger.info("OpenCL available={}, activated={}", haveOpenCL, useOpenCL);
|
||||
int cudacount = opencv_core.getCudaEnabledDeviceCount();
|
||||
if (cudacount>0){
|
||||
Logger.info("CUDA enabled devices found: " + cudacount);
|
||||
opencv_core.printCudaDeviceInfo(0);
|
||||
} else {
|
||||
Logger.info("No CUDA enabled devices found");
|
||||
}
|
||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||
String targetip = config.getProperty("Camera_ip");
|
||||
String rtsppath = config.getProperty("Camera_Rtsp_path");
|
||||
System.out.println("Camera IP : "+targetip);
|
||||
System.out.println("Camera Rtsp Path : "+rtsppath);
|
||||
Logger.info("Camera IP : "+targetip);
|
||||
Logger.info("Camera Rtsp Path : "+rtsppath);
|
||||
rtspGrabber = null;
|
||||
if (ValidString(targetip)){
|
||||
if (ValidString(rtsppath)){
|
||||
if (IpIsReachable(targetip)){
|
||||
Logger.info("Camera IP : "+targetip+" is reachable");
|
||||
rtspGrabber = new RtspGrabber(targetip, rtsppath);
|
||||
rtspGrabber = new RtspGrabber(targetip, rtsppath, use_Yolo);
|
||||
rtspGrabber.Start(true, 1920, 1080);
|
||||
} else System.out.println("Camera IP : "+targetip+" is not reachable");
|
||||
} else System.out.println("Camera Path : "+rtsppath+" is not valid string");
|
||||
} else System.out.println("Camera IP : "+targetip+" is not valid string");
|
||||
} else Logger.warn("Camera IP : "+targetip+" is not reachable");
|
||||
} else Logger.warn("Camera Path : "+rtsppath+" is not valid string");
|
||||
} else Logger.warn("Camera IP : "+targetip+" is not valid string");
|
||||
}
|
||||
|
||||
private static void init_multiusb_audio(){
|
||||
multiUSBAudioPlayer = new MultiUSBAudioPlayer();
|
||||
multiUSBAudioPlayer.DetectOutputDevices();
|
||||
int[] devs = multiUSBAudioPlayer.FindDeviceIDWithName("USB");
|
||||
if (devs!=null && devs.length>0){
|
||||
Logger.info("MultiUSB Audio Device found : {}", IntArrayToString(devs));
|
||||
if (multiUSBAudioPlayer.OpenDevice(devs, 48000)){
|
||||
multiUSBAudioPlayer.setMasterVolume(100);
|
||||
multiUSBAudioPlayer.setPlaybackvolume(100);
|
||||
Logger.info("MultiUSB Audio Device ID={} opened", IntArrayToString(devs));
|
||||
} else Logger.error("Failed to open MultiUSB Audio Device ID={}", IntArrayToString(devs));
|
||||
} else Logger.error("MultiUSB Audio Device not found");
|
||||
}
|
||||
|
||||
private static void init_audio() {
|
||||
@@ -494,10 +570,18 @@ public class Main {
|
||||
return new WebsocketReply("STOP MOVEMENT", "");
|
||||
// Audio Related Commands
|
||||
case "MUTE":
|
||||
if (audioPlayer!=null) audioPlayer.Mute();
|
||||
if (use_multiusb_audio){
|
||||
if (multiUSBAudioPlayer!=null) multiUSBAudioPlayer.Mute();
|
||||
} else {
|
||||
if (audioPlayer!=null) audioPlayer.Mute();
|
||||
}
|
||||
return new WebsocketReply("MUTE", "");
|
||||
case "UNMUTE":
|
||||
if (audioPlayer!=null) audioPlayer.Unmute();
|
||||
if (use_multiusb_audio){
|
||||
if (multiUSBAudioPlayer!=null) multiUSBAudioPlayer.Unmute();
|
||||
} else {
|
||||
if (audioPlayer!=null) audioPlayer.Unmute();
|
||||
}
|
||||
return new WebsocketReply("UNMUTE", "");
|
||||
case "SET VOLUME" :
|
||||
int volume=-1;
|
||||
@@ -507,11 +591,20 @@ public class Main {
|
||||
if (volume>100) volume = 100;
|
||||
}
|
||||
if (volume>=0){
|
||||
if (audioPlayer!=null) audioPlayer.setPlaybackvolume(volume);
|
||||
return new WebsocketReply("SET VOLUME", String.valueOf(volume));
|
||||
if (use_multiusb_audio){
|
||||
if (multiUSBAudioPlayer!=null) multiUSBAudioPlayer.setPlaybackvolume(volume);
|
||||
} else{
|
||||
if (audioPlayer!=null) audioPlayer.setPlaybackvolume(volume);
|
||||
}
|
||||
return new WebsocketReply("SET VOLUME", String.valueOf(volume));
|
||||
} else return new WebsocketReply("SET VOLUME", "Invalid Volume Value");
|
||||
case "GET VOLUME" :
|
||||
int vol = audioPlayer!=null ? audioPlayer.getPlaybackvolume() : 0;
|
||||
int vol = 0;
|
||||
if (use_multiusb_audio){
|
||||
if (multiUSBAudioPlayer!=null) vol = multiUSBAudioPlayer.getPlaybackvolume();
|
||||
} else {
|
||||
if (audioPlayer!=null) vol = audioPlayer.getPlaybackvolume();
|
||||
}
|
||||
return new WebsocketReply("GET VOLUME", String.valueOf(vol));
|
||||
case "PLAY AUDIO" :
|
||||
if (ValidInteger(command.data)){
|
||||
@@ -520,25 +613,45 @@ public class Main {
|
||||
if (ValidString(filename)){
|
||||
File filetoplay = new File(Path.of(currentDirectory, "audiofiles", filename).toString());
|
||||
if (filetoplay.isFile()){
|
||||
AudioFileProperties afp = audioPlayer.OpenAudioFile(filetoplay);
|
||||
if (afp!=null){
|
||||
audioFileProperties = afp;
|
||||
audioPlayer.PlayAudioFile(afp, true, pe);
|
||||
//AmplifierControl(true);
|
||||
return new WebsocketReply("PLAY AUDIO", afp.filename);
|
||||
if (use_multiusb_audio){
|
||||
MultiUSBAudioPlayer.PlaybackHandlewithId[] phs = multiUSBAudioPlayer.OpenAudioFile(filetoplay);
|
||||
if (phs!=null && phs.length>0){
|
||||
playbackHandles = phs;
|
||||
multiUSBAudioPlayer.PlayAudioFile(phs, true, pe);
|
||||
return new WebsocketReply("PLAY AUDIO", filename);
|
||||
}
|
||||
return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
|
||||
} else {
|
||||
AudioFileProperties afp = audioPlayer.OpenAudioFile(filetoplay);
|
||||
if (afp!=null){
|
||||
audioFileProperties = afp;
|
||||
audioPlayer.PlayAudioFile(afp, true, pe);
|
||||
//AmplifierControl(true);
|
||||
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", String.format("AudioFile with ID %02d not found", id));
|
||||
} else return new WebsocketReply("PLAY AUDIO", "Invalid Audio ID");
|
||||
case "STOP AUDIO" :
|
||||
if (audioFileProperties!=null){
|
||||
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
|
||||
String filename = audioFileProperties.filename;
|
||||
audioFileProperties = null;
|
||||
//AmplifierControl(false);
|
||||
return new WebsocketReply("STOP AUDIO", filename);
|
||||
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
|
||||
if (use_multiusb_audio){
|
||||
if (playbackHandles!=null && playbackHandles.length>0){
|
||||
multiUSBAudioPlayer.CloseAudioFile(playbackHandles);
|
||||
String filename = playbackHandles[0].handle.filename;
|
||||
playbackHandles = null;
|
||||
return new WebsocketReply("STOP AUDIO", filename);
|
||||
} else return new WebsocketReply("STOP AUDIO", "No playbackHandles");
|
||||
} else {
|
||||
if (audioFileProperties!=null){
|
||||
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
|
||||
String filename = audioFileProperties.filename;
|
||||
audioFileProperties = null;
|
||||
//AmplifierControl(false);
|
||||
return new WebsocketReply("STOP AUDIO", filename);
|
||||
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
|
||||
}
|
||||
|
||||
// ZOOM Related Commands
|
||||
case "GET MAX ZOOM":
|
||||
if (vapixProtocol!=null){
|
||||
@@ -551,29 +664,43 @@ public class Main {
|
||||
return new WebsocketReply("GET ZOOM", String.valueOf(vapixProtocol.GetCurrentZoomValue()));
|
||||
} else return new WebsocketReply("GET ZOOM", "VapixProtocol not initialized");
|
||||
case "SET ZOOM":
|
||||
if (vapixProtocol.PTZEnabled()){
|
||||
if (ValidInteger(command.data)){
|
||||
int zoom = Integer.parseInt(command.data);
|
||||
if (zoom<vapixProtocol.GetPTZMinZoom()) zoom = vapixProtocol.GetPTZMinZoom();
|
||||
if (zoom>vapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
|
||||
if (vapixProtocol.Zoom(1, zoom)){
|
||||
if (vapixProtocol!=null){
|
||||
if (vapixProtocol.PTZEnabled()){
|
||||
if (ValidInteger(command.data)){
|
||||
int zoom = Integer.parseInt(command.data);
|
||||
if (zoom<vapixProtocol.GetPTZMinZoom()) zoom = vapixProtocol.GetPTZMinZoom();
|
||||
if (zoom>vapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
|
||||
Blink_LedIpCamera();
|
||||
return new WebsocketReply("ZOOM", String.valueOf(zoom));
|
||||
} else return new WebsocketReply("ZOOM", "Failed to zoom");
|
||||
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
|
||||
} else return new WebsocketReply("ZOOM", "Zoom not supported");
|
||||
if (vapixProtocol.Zoom(1, zoom)){
|
||||
return new WebsocketReply("ZOOM", String.valueOf(zoom));
|
||||
} else return new WebsocketReply("ZOOM", "Failed to zoom");
|
||||
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
|
||||
} else return new WebsocketReply("ZOOM", "Zoom not supported");
|
||||
}
|
||||
|
||||
// Live Streaming Related Commands
|
||||
case "GET BASE64":
|
||||
if (rtspGrabber!=null){
|
||||
return switch (command.data) {
|
||||
case "YOLO" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
|
||||
case "LQ" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
|
||||
case "HQ" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastYoloBase64(), rtspGrabber.HQStreamingStatus());
|
||||
default -> new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||
};
|
||||
if (use_Yolo){
|
||||
return switch (command.data) {
|
||||
case "HQ" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
|
||||
case "LQ" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
|
||||
case "YOLO" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastYoloBase64(), rtspGrabber.LQStreamingStatus());
|
||||
default -> new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||
};
|
||||
} else {
|
||||
return switch (command.data) {
|
||||
case "HQ" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
|
||||
case "LQ" ->
|
||||
new WebsocketReply("GET BASE64", "data:image/jpeg;base64," + rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
|
||||
default -> new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||
};
|
||||
}
|
||||
|
||||
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||
case "GET RESOLUTION":
|
||||
if (vapixProtocol!=null){
|
||||
|
||||
Reference in New Issue
Block a user