diff --git a/scripts/spectrogram.php b/scripts/spectrogram.php index 832dd4d..65acd29 100644 --- a/scripts/spectrogram.php +++ b/scripts/spectrogram.php @@ -14,18 +14,65 @@ $RECS_DIR = $config["RECS_DIR"]; $user = shell_exec("awk -F: '/1000/{print $1}' /etc/passwd"); $home = shell_exec("awk -F: '/1000/{print $6}' /etc/passwd"); $home = trim($home); -$files = scandir($RECS_DIR."/".date('F-Y')."/".date('d-l')."/", SCANDIR_SORT_ASCENDING); + +//Replace variables to Fix up the file paths just in case the ENV environment variables don't resolve via PHP +$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 +$look_in_directory = $RECS_DIR."/".date('F-Y')."/".date('d-l')."/"; +$files = scandir($look_in_directory, SCANDIR_SORT_ASCENDING); +//Extract the filename, positions 0 and 1 are the folder hierarchy '.' and '..' $newest_file = $files[2]; +//Couldn't find under e.g /home/pi/April-2023/03-Monday/ (where USB audio streams are recorded +//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; + //Load the file in the directory + $files = scandir($look_in_directory, SCANDIR_SORT_ASCENDING); + + //Because there might be more than 1 stream, we can't really assume the file at index 2 is the latest, or even for the stream being listened to + //Read the RTSP_STREAM_TO_LIVESTREAM setting, then try to find that CSV file + if(!empty($config['RTSP_STREAM_TO_LIVESTREAM']) && is_numeric($config['RTSP_STREAM_TO_LIVESTREAM'])){ + //The stored setting of RTSP_STREAM_TO_LIVESTREAM is 0 based, but filenames are 1's based, so just add 1 to the config value + //so we can match up the stream the user is listening to with the appropriate filename + $RTSP_STREAM_LISTENED_TO = ($config['RTSP_STREAM_TO_LIVESTREAM'] + 1); + }else{ + //Setting is invalid somehow + //The stored setting of RTSP_STREAM_TO_LIVESTREAM is 0 based, but filenames are 1's based, so just add 1 to the config value + //This will be the first stream + $RTSP_STREAM_LISTENED_TO = 1; + } + + //The RTSP streams contain 'RTSP_X' in the filename, were X is the stream url index in the comma separated list of RTSP streams + //We can use this to locate the file for this stream + foreach ($files as $file_idx => $stream_file_name) { + //Skip the folder hierarchy entries + 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 + if (stripos($stream_file_name, 'RTSP_' . $RTSP_STREAM_LISTENED_TO) !== false && stripos($stream_file_name, '.wav.csv') === false) { + //Found a match - set it as the newest file + $newest_file = $stream_file_name; + } + } + } + } + + +//If the newest file param has been supplied and it's the same as the newest file found +//then stop processing if($newest_file == $_GET['newest_file']) { die(); } +//Print out the filename echo "file,".$newest_file."\n"; +//Print out the detected birds as CSV $row = 1; -if (($handle = fopen($RECS_DIR."/".date('F-Y')."/".date('d-l')."/".$newest_file.".csv", "r")) !== FALSE) { +if (($handle = fopen($look_in_directory . $newest_file . ".csv", "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { if($row != 1){ $num = count($data); @@ -38,23 +85,25 @@ if (($handle = fopen($RECS_DIR."/".date('F-Y')."/".date('d-l')."/".$newest_file. } fclose($handle); } +//Kill the script so no further processing or output is done die(); } -$RSTP_Stream_Config = array(); +//Hold the array of RTSP steams once they are exploded +$RTSP_Stream_Config = array(); -//Load the birdnet config so we can read the RSTP setting +//Load the birdnet config so we can read the RTSP setting // Valid config data if (is_array($config) && array_key_exists('RTSP_STREAM',$config)) { if (is_null($config['RTSP_STREAM']) === false && $config['RTSP_STREAM'] !== "") { - $RSTP_Stream_Config_Data = explode(",", $config['RTSP_STREAM']); + $RTSP_Stream_Config_Data = explode(",", $config['RTSP_STREAM']); //Process the stream further //we need to able to ID it (just do this by position), get the hostname to show in the dropdown box - foreach ($RSTP_Stream_Config_Data as $stream_idx => $stream_url) { + foreach ($RTSP_Stream_Config_Data as $stream_idx => $stream_url) { //$stream_idx is the array position of the the RSP stream URL, idx of 0 is the first, 1 - second etc - $rstp_stream_url = parse_url($stream_url); - $RSTP_Stream_Config[$stream_idx] = $rstp_stream_url['host']; + $RTSP_stream_url = parse_url($stream_url); + $RTSP_Stream_Config[$stream_idx] = $RTSP_stream_url['host']; } } } @@ -159,21 +208,27 @@ function applyText(text,x,y,opacity) { var add =0; var newest_file; +var newest_file_tmp; var lastbird; function loadDetectionIfNewExists() { const xhttp = new XMLHttpRequest(); xhttp.onload = function() { // if there's a new detection that needs to be updated to the page if(this.responseText.length > 0 && !this.responseText.includes("Database")) { - + // Case insensitive match for RTSP_X + var RTSP_regex = /RTSP_[0-9]+-/i; + var RTSP_regex_match = false; var split = this.responseText.split("\n") for(var i = 1;i < split.length; i++) { if(parseInt(split[i].split(",")[0]) >= 0){ newest_file = split[0].split(",")[1] + newest_file_tmp = newest_file;//Copy the file name var so we something to work with + //Remove the string that denotes the RTSP stream from the filename to make things easier, it's not really needed + RTSP_regex_match = RTSP_regex.test(newest_file_tmp) + newest_file_tmp = newest_file_tmp.replace(RTSP_regex, "") //applyText(split[i].split(",")[1],document.body.querySelector('canvas').width - ((parseInt(split[i].split(",")[0]))*avgfps), (document.body.querySelector('canvas').height * 0.50)) - - d1 = new Date(newest_file.split("-")[0]+"/"+newest_file.split("-")[1]+"/"+newest_file.split("-")[2]+ " "+newest_file.split("-")[4].replace(".wav","")) + 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","")) console.log("d1 "+d1) d2 = new Date(xhttp.getResponseHeader("Date")); console.log("d2 "+d2) @@ -193,7 +248,13 @@ function loadDetectionIfNewExists() { console.log(add) // Date csv file was created + relative detection time of bird + mic delay - secago = Math.abs(timeDiff) - split[i].split(",")[0] - 6.8; + //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 @@ -361,16 +422,16 @@ h1 {
-
+