diff --git a/birdnet.conf-defaults b/birdnet.conf-defaults
index 5863aab..f21fcad 100644
--- a/birdnet.conf-defaults
+++ b/birdnet.conf-defaults
@@ -48,6 +48,13 @@ ICE_PWD=birdnetpi
BIRDNETPI_URL=
+#---------------------------- RTSP Stream URL -------------------------------#
+
+## If RTSP_STREAM is set, the system will use the RTSP stream as its audio
+## source instead of recording its own audio. If this variable is kept empty,
+## BirdNET-Pi will default to recording its own audio.
+
+RTSP_STREAM=
#------------------- Mobile Notifications via Pushed.co ---------------------#
#____________The two variables below enable mobile notifications_______________#
diff --git a/scripts/advanced.php b/scripts/advanced.php
index a4da847..b73bfbe 100644
--- a/scripts/advanced.php
+++ b/scripts/advanced.php
@@ -64,6 +64,19 @@ if(isset($_GET['submit'])) {
}
}
+ if(isset($_GET["rtsp_stream"])) {
+ $rtsp_stream = str_replace("\r\n", ",", $_GET["rtsp_stream"]);
+ if(strcmp($rtsp_stream,$config['RTSP_STREAM']) !== 0) {
+ $contents = preg_replace("/RTSP_STREAM=.*/", "RTSP_STREAM=$rtsp_stream", $contents);
+ $contents2 = preg_replace("/RTSP_STREAM=.*/", "RTSP_STREAM=$rtsp_stream", $contents2);
+ $fh = fopen('/etc/birdnet/birdnet.conf', "w");
+ $fh2 = fopen("./scripts/thisrun.txt", "w");
+ fwrite($fh, $contents);
+ fwrite($fh2, $contents2);
+ exec('sudo systemctl restart birdnet_recording.service');
+ }
+ }
+
if(isset($_GET["overlap"])) {
$overlap = $_GET["overlap"];
if(strcmp($overlap,$config['OVERLAP']) !== 0) {
@@ -108,14 +121,14 @@ if(isset($_GET['submit'])) {
$contents2 = preg_replace("/PRIVACY_MODE=.*/", "PRIVACY_MODE=$privacy_mode", $contents2);
if(strcmp($privacy_mode,"on") == 0) {
exec('sudo sed -i \'s/\/usr\/local\/bin\/server.py/\/usr\/local\/bin\/privacy_server.py/g\' ../../BirdNET-Pi/templates/birdnet_server.service');
- exec('sudo systemctl daemon-reload');
- exec('restart_services.sh');
- header('Location: /log');
+ exec('sudo systemctl daemon-reload');
+ exec('restart_services.sh');
+ header('Location: /log');
} elseif(strcmp($privacy_mode,"off") == 0) {
exec('sudo sed -i \'s/\/usr\/local\/bin\/privacy_server.py/\/usr\/local\/bin\/server.py/g\' ../../BirdNET-Pi/templates/birdnet_server.service');
- exec('sudo systemctl daemon-reload');
- exec('restart_services.sh');
- header('Location: /log');
+ exec('sudo systemctl daemon-reload');
+ exec('restart_services.sh');
+ header('Location: /log');
}
}
}
@@ -201,6 +214,9 @@ if (file_exists('./scripts/thisrun.txt')) {
Set Channels to the number of channels supported by your sound card. 32 max.
+ +If you place an RTSP stream URL here, BirdNET-Pi will use that as its audio source. If you have multiple streams, each URL should be on its own line.
Set Recording Length in seconds between 6 and 60. Multiples of 3 are recommended, as BirdNET analyzes in 3-second chunks.
diff --git a/scripts/birdnet_recording.sh b/scripts/birdnet_recording.sh index 0798511..ccd1024 100755 --- a/scripts/birdnet_recording.sh +++ b/scripts/birdnet_recording.sh @@ -2,29 +2,29 @@ set -x source /etc/birdnet/birdnet.conf -if [ "${TIMESTAMP_FORMAT}" == "12" ];then - STAMP="%I:%M:%S%P" -else - STAMP="%H:%M:%S" -fi - [ -z $RECORDING_LENGTH ] && RECORDING_LENGTH=15 -if ! pulseaudio --check;then pulseaudio --start;fi - -if pgrep arecord &> /dev/null ;then - echo "Recording" -else - until grep 5050 <(netstat -tulpn 2>&1);do - sleep 1 +if [ ! -z $RTSP_STREAM ];then + while true;do + for i in ${RTSP_STREAM//,/ };do + ffmpeg -i ${i} -t 15 -vn -acodec pcm_s16le -ac 2 -ar 48000 file:${RECS_DIR}/$(date "+%F")-birdnet-$(date "+%H:%M:%S").wav /dev/null 2>&1 & sleep 1; + done done - if [ -z ${REC_CARD} ];then - - arecord -f S16_LE -c${CHANNELS} -r48000 -t wav --max-file-time ${RECORDING_LENGTH}\ - --use-strftime ${RECS_DIR}/%B-%Y/%d-%A/%F-birdnet-${STAMP}.wav +else + if ! pulseaudio --check;then pulseaudio --start;fi + if pgrep arecord &> /dev/null ;then + echo "Recording" else - arecord -f S16_LE -c${CHANNELS} -r48000 -t wav --max-file-time ${RECORDING_LENGTH}\ - -D "${REC_CARD}" --use-strftime \ - ${RECS_DIR}/%B-%Y/%d-%A/%F-birdnet-${STAMP}.wav + until grep 5050 <(netstat -tulpn 2>&1);do + sleep 1 + done + if [ -z ${REC_CARD} ];then + arecord -f S16_LE -c${CHANNELS} -r48000 -t wav --max-file-time ${RECORDING_LENGTH}\ + --use-strftime ${RECS_DIR}/%B-%Y/%d-%A/%F-birdnet-%H:%M:%S.wav + else + arecord -f S16_LE -c${CHANNELS} -r48000 -t wav --max-file-time ${RECORDING_LENGTH}\ + -D "${REC_CARD}" --use-strftime \ + ${RECS_DIR}/%B-%Y/%d-%A/%F-birdnet-%H:%M:%S.wav + fi fi fi diff --git a/scripts/extract_new_birdsounds.sh b/scripts/extract_new_birdsounds.sh index 947802b..1d94c70 100755 --- a/scripts/extract_new_birdsounds.sh +++ b/scripts/extract_new_birdsounds.sh @@ -13,9 +13,9 @@ source /etc/birdnet/birdnet.conf # Set Variables TMPFILE=$(mktemp) -ANALYZED=${RECS_DIR}/*/*Analyzed -# SCAN_DIRS are all directories marked "Analyzed" -SCAN_DIRS=($(find ${ANALYZED} -type d 2>/dev/null | sort )) +#ANALYZED=${RECS_DIR}/*/*Analyzed +#SCAN_DIRS are all directories marked "Analyzed" +SCAN_DIRS=($(find $HOME -type d -name '*Analyzed' 2>/dev/null | sort )) for h in "${SCAN_DIRS[@]}";do # The TMPFILE is created from each .csv file BirdNET creates @@ -30,13 +30,14 @@ for h in "${SCAN_DIRS[@]}";do for i in $(find ${h} -name '*csv' 2>/dev/null | sort );do # Iterates over each '.csv' file found in each "Analyzed" directory # to create the TMPFILE - echo "${i}" | cut -d'/' -f7 >> ${TMPFILE} + echo "$(basename ${i})" >> ${TMPFILE} sort -k1n -t\; "${i}" | awk '!/Start/{print}' >> ${TMPFILE} done # The extraction reads each line of the TMPFILE and sets the variables ffmpeg # will use. while read -r line;do + echo "Line = $line" DATE="$(echo "${line}" \ | awk -F- '/birdnet/{print $1"-"$2"-"$3}')" if [ ! -z ${DATE} ];then diff --git a/scripts/install_config.sh b/scripts/install_config.sh index e6ed905..351c3a2 100755 --- a/scripts/install_config.sh +++ b/scripts/install_config.sh @@ -61,6 +61,13 @@ ICE_PWD=birdnetpi BIRDNETPI_URL= +#---------------------------- RTSP Stream URL -------------------------------# + +## If RTSP_STREAM is set, the system will use the RTSP stream as its audio +## source instead of recording its own audio. If this variable is kept empty, +## BirdNET-Pi will default to recording its own audio. + +RTSP_STREAM= #------------------- Mobile Notifications via Pushed.co ---------------------# #____________The two variables below enable mobile notifications_______________# diff --git a/scripts/livestream.sh b/scripts/livestream.sh index bdebba7..d081d53 100755 --- a/scripts/livestream.sh +++ b/scripts/livestream.sh @@ -4,8 +4,12 @@ source /etc/birdnet/birdnet.conf if [ -z ${REC_CARD} ];then echo "Stream not supported" -else - ffmpeg -loglevel 52 -ac ${CHANNELS} -f alsa -i ${REC_CARD} -acodec libmp3lame \ +elif [[ ! -z ${RTSP_STREAM} ]];then + ffmpeg -loglevel 52 -ac ${CHANNELS} -i ${RTSP_STREAM} -acodec libmp3lame \ -b:a 320k -ac ${CHANNELS} -content_type 'audio/mpeg' \ -f mp3 icecast://source:${ICE_PWD}@localhost:8000/stream -re -fi +else + ffmpeg -loglevel 52 -ac ${CHANNELS} -f alsa -i ${REC_CARD} -acodec libmp3lame \ + -b:a 320k -ac ${CHANNELS} -content_type 'audio/mpeg' \ + -f mp3 icecast://source:${ICE_PWD}@localhost:8000/stream -re +fi \ No newline at end of file diff --git a/scripts/update_birdnet.sh b/scripts/update_birdnet.sh index a48e7d6..dd6e84a 100755 --- a/scripts/update_birdnet.sh +++ b/scripts/update_birdnet.sh @@ -18,3 +18,6 @@ fi if ! grep PRIVACY_MODE /etc/birdnet/birdnet.conf;then sudo -u${USER} echo "PRIVACY_MODE=off" >> /etc/birdnet/birdnet.conf fi +if ! grep RTSP_STREAM /etc/birdnet/birdnet.conf;then + sudo -u${USER} echo "RTSP_STREAM=" >> /etc/birdnet/birdnet.conf +fi