with the new analysis pipeline .wav and .wav.json do not exist at the same time. make labeling work with json alone. also tweak the timing

This commit is contained in:
frederik
2024-03-12 13:48:47 +01:00
parent 1f7aad7873
commit 6c6247cf19
+45 -95
View File
@@ -15,25 +15,21 @@ if(!empty($config['FREQSHIFT_RECONNECT_DELAY']) && is_numeric($config['FREQSHIFT
} }
if(isset($_GET['ajax_csv'])) { if(isset($_GET['ajax_csv'])) {
$RECS_DIR = $config["RECS_DIR"]; $RECS_DIR = $config["RECS_DIR"];
$user = shell_exec("awk -F: '/1000/{print $1}' /etc/passwd"); $user = shell_exec("awk -F: '/1000/{print $1}' /etc/passwd");
$home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd"); $home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd");
$home = trim($home); $home = trim($home);
//Replace variables to Fix up the file paths just in case the ENV environment variables don't resolve via PHP $STREAM_DATA_DIR = $RECS_DIR . "/StreamData/";
$RECS_DIR = str_replace("\$HOME", $home, $RECS_DIR);
$STREAM_DATA_DIR = $RECS_DIR . "/StreamData/";
//Try find the latest file out of the soundcard recording folder if (empty($config['RTSP_STREAM'])) {
$look_in_directory = $RECS_DIR."/".date('F-Y')."/".date('d-l')."/"; $look_in_directory = $STREAM_DATA_DIR;
$files = scandir($look_in_directory, SCANDIR_SORT_ASCENDING); $files = scandir($look_in_directory, SCANDIR_SORT_ASCENDING);
//Extract the filename, positions 0 and 1 are the folder hierarchy '.' and '..' //Extract the filename, positions 0 and 1 are the folder hierarchy '.' and '..'
$newest_file = $files[2]; $newest_file = $files[2];
}
//Couldn't find under e.g /home/pi/April-2023/03-Monday/ (where USB audio streams are recorded else {
//look in the StreamData directory (RTSP streams are recorded here)
if (empty($files) || array_key_exists(2, $files) === false) {
$look_in_directory = $STREAM_DATA_DIR; $look_in_directory = $STREAM_DATA_DIR;
//Load the file in the directory //Load the file in the directory
@@ -57,14 +53,14 @@ $newest_file = $files[2];
foreach ($files as $file_idx => $stream_file_name) { foreach ($files as $file_idx => $stream_file_name) {
//Skip the folder hierarchy entries //Skip the folder hierarchy entries
if ($stream_file_name != "." && $stream_file_name != "..") { if ($stream_file_name != "." && $stream_file_name != "..") {
//See if the filename contains the correct RTSP name, also only check .wav files by excluding the csv files with the filter .wav.csv //See if the filename contains the correct RTSP name, also only check .wav.csv files
if (stripos($stream_file_name, 'RTSP_' . $RTSP_STREAM_LISTENED_TO) !== false && stripos($stream_file_name, '.wav.csv') === false) { if (stripos($stream_file_name, 'RTSP_' . $RTSP_STREAM_LISTENED_TO) !== false && stripos($stream_file_name, '.wav.json') !== false) {
//Found a match - set it as the newest file //Found a match - set it as the newest file
$newest_file = $stream_file_name; $newest_file = $stream_file_name;
} }
} }
} }
} }
//If the newest file param has been supplied and it's the same as the newest file found //If the newest file param has been supplied and it's the same as the newest file found
@@ -73,24 +69,18 @@ if($newest_file == $_GET['newest_file']) {
die(); die();
} }
//Print out the filename $contents = file_get_contents($look_in_directory . $newest_file);
echo "file,".$newest_file."\n"; if ($contents !== false) {
$json = json_decode($contents);
//Print out the detected birds as CSV if ($json != null) {
$row = 1; $datetime = DateTime::createFromFormat(DateTime::ISO8601, $json->{'timestamp'});
if (($handle = fopen($look_in_directory . $newest_file . ".csv", "r")) !== FALSE) { $now = new DateTime();
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $interval = $now->diff($datetime);
if($row != 1){ $json->delay = $interval->format('%s');
$num = count($data); echo json_encode($json);
for ($c=0; $c < $num; $c++) {
$exp = explode(';',$data[$c]);
echo (($exp[0]+$exp[1])/2).",".$exp[3].",".$exp[4]."\n";
} }
}
$row++;
}
fclose($handle);
} }
//Kill the script so no further processing or output is done //Kill the script so no further processing or output is done
die(); die();
} }
@@ -212,84 +202,44 @@ function applyText(text,x,y,opacity) {
CTX.fillStyle = 'hsl(280, 100%, 10%)'; CTX.fillStyle = 'hsl(280, 100%, 10%)';
} }
var add =0; var add=0;
var newest_file; var newest_file;
var newest_file_tmp;
var lastbird;
function loadDetectionIfNewExists() { function loadDetectionIfNewExists() {
const xhttp = new XMLHttpRequest(); const xhttp = new XMLHttpRequest();
xhttp.onload = function() { xhttp.onload = function() {
// if there's a new detection that needs to be updated to the page // if there's a new detection that needs to be updated to the page
if(this.responseText.length > 0 && !this.responseText.includes("Database")) { if(this.responseText.length > 0 && !this.responseText.includes("Database")) {
// Case insensitive match for RTSP_X const resp = JSON.parse(this.responseText);
var RTSP_regex = /RTSP_[0-9]+-/i; newest_file = resp.file_name;
var RTSP_regex_match = false; console.log("delay " + resp.delay);
var split = this.responseText.split("\n") for (detection of resp.detections) {
for(var i = 1;i < split.length; i++) { console.log("detection.start " + detection.start);
if(parseInt(split[i].split(",")[0]) >= 0){ secago = resp.delay - detection.start;
x = document.body.querySelector('canvas').width - (secago * avgfps);
newest_file = split[0].split(",")[1] y = (document.body.querySelector('canvas').height * 0.50) + add;
newest_file_tmp = newest_file;//Copy the file name var so we something to work with if(x > document.body.querySelector('canvas').width - (5*avgfps) && detection.common_name.length > 8) {
//Remove the string that denotes the RTSP stream from the filename to make things easier, it's not really needed setTimeout(function (detection, x, y, x_org) {
RTSP_regex_match = RTSP_regex.test(newest_file_tmp) console.log("originally at "+x_org+", now waiting 3 sec and at "+x);
newest_file_tmp = newest_file_tmp.replace(RTSP_regex, "") applyText(detection.common_name, x, y, detection.confidence);
//applyText(split[i].split(",")[1],document.body.querySelector('canvas').width - ((parseInt(split[i].split(",")[0]))*avgfps), (document.body.querySelector('canvas').height * 0.50)) }, 3*1000, detection, x - (5*avgfps), y, x);
d1 = new Date(newest_file_tmp.split("-")[0]+"/"+newest_file_tmp.split("-")[1]+"/"+newest_file_tmp.split("-")[2]+ " "+newest_file_tmp.split("-")[4].replace(".wav","")) } else {
console.log("d1 "+d1) applyText(detection.common_name, x, y, detection.confidence);
d2 = new Date(xhttp.getResponseHeader("Date")); }
console.log("d2 "+d2) // stagger Y placement
timeDiff = (d2-d1)/1000;
// stagger Y placement if a new bird
if(split[i].split(",")[1] != lastbird || split[i].split(",")[1].length > 13) {
add+= 15; add+= 15;
if(add >= 60) { if(add >= 60) {
add = 0; add = 0;
} }
//if(parseFloat(add + document.body.querySelector('canvas').height * 0.50) > document.body.querySelector('canvas').height || parseFloat(add + document.body.querySelector('canvas').height * 0.50) <= 0) {
// add = 0;
//}
}
console.log(add)
// Date csv file was created + relative detection time of bird + mic delay
//If we can't find the regex in the filename, then the RTSP_X string doesn't exist, unlikely to be a RTSP stream
if (RTSP_regex_match == false){
secago = (Math.abs(timeDiff) - split[i].split(",")[0]) - 6.8;
}else{
//half the delay for RTSP streams ~ just a rough guess
secago = (Math.abs(timeDiff) - split[i].split(",")[0]) - 4;
}
x = document.body.querySelector('canvas').width - ((parseInt(secago))*avgfps);
// if the text is too close to the right side of the canvas and will be cut off, wait 3 seconds before adding text
if(x > document.body.querySelector('canvas').width - (3*avgfps)) {
setTimeout(function (split,i,x,add) {
console.log("ADD:"+add)
console.log(split[i])
console.log("originally at "+x+", now waiting 2 sec and at "+(x-(3*avgfps)))
applyText(split[i].split(",")[1],(x - (3*avgfps)), ((document.body.querySelector('canvas').height * 0.50) + add ), split[i].split(",")[2]);
}, 2000, split, i, x, add)
} else {
applyText(split[i].split(",")[1],x, ((document.body.querySelector('canvas').height * 0.50) + add ), split[i].split(",")[2])
}
lastbird = split[i].split(",")[1]
}
}
} }
} }
};
xhttp.open("GET", "spectrogram.php?ajax_csv=true&newest_file="+newest_file, true); xhttp.open("GET", "spectrogram.php?ajax_csv=true&newest_file="+newest_file, true);
xhttp.send(); xhttp.send();
} }
window.setInterval(function(){ window.setInterval(function(){
loadDetectionIfNewExists(); loadDetectionIfNewExists();
}, 500); }, 1000);
var compressor = undefined; var compressor = undefined;
var SOURCE; var SOURCE;