From 5aad9c980d28d5dab7b118d6d7d5062d7b6860cd Mon Sep 17 00:00:00 2001 From: bel Date: Sat, 31 Aug 2024 11:25:08 -0600 Subject: [PATCH] moonfire-nvr is fire --- testdata/moonfire-nvr/install.txt | 1 + testdata/moonfire-nvr/setup.sh | 25 ++++ ...movement_detection_to_rclone_via_ffmpeg.sh | 57 +++++++++ testdata/record_rtsp_via_ffmpeg.sh | 117 ++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 testdata/moonfire-nvr/install.txt create mode 100644 testdata/moonfire-nvr/setup.sh create mode 100644 testdata/movement_detection_to_rclone_via_ffmpeg.sh create mode 100755 testdata/record_rtsp_via_ffmpeg.sh diff --git a/testdata/moonfire-nvr/install.txt b/testdata/moonfire-nvr/install.txt new file mode 100644 index 0000000..214c9e5 --- /dev/null +++ b/testdata/moonfire-nvr/install.txt @@ -0,0 +1 @@ +https://github.com/scottlamb/moonfire-nvr/blob/master/guide/install.md diff --git a/testdata/moonfire-nvr/setup.sh b/testdata/moonfire-nvr/setup.sh new file mode 100644 index 0000000..14879f9 --- /dev/null +++ b/testdata/moonfire-nvr/setup.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +read -p "going to: https://github.com/scottlamb/moonfire-nvr/blob/master/guide/install.md as /etc/moonfire-nvr.toml" +echo ' +[[binds]] +ipv4 = "0.0.0.0:29898" +allowUnauthenticatedPermissions = { viewVideo = true } + +[[binds]] +unix = "/var/lib/moonfire-nvr/sock" +ownUidIsPrivileged = true +' | sudo tee /etc/moonfire-nvr.toml + +sudo mkdir -p /var/lib/moonfire-nvr +sudo chmod -R 777 /var/lib/moonfire-nvr + +moonfire-nvr init + +read -p "1. create a SAMPLE DIR first," +read -p "2. use like rtsp://192.168.0.83:8554/unicast with RECORD and DIR for MAIN and SUB" +read -p "3. modify SAMPLE DIR to retain N Mbps_/_8_*_120s disk (wyze at home is 5Mbps, so 75MB per 2min file (54GB per day) if noisy?)" +moonfire-nvr config + +open http://localhost:29898 +read -p "moonfire-nvr run" diff --git a/testdata/movement_detection_to_rclone_via_ffmpeg.sh b/testdata/movement_detection_to_rclone_via_ffmpeg.sh new file mode 100644 index 0000000..8f92666 --- /dev/null +++ b/testdata/movement_detection_to_rclone_via_ffmpeg.sh @@ -0,0 +1,57 @@ +#! /bin/bash +disabled="false" +threshold="0.040" +vdir=/tmp/tmpfs +exec > >(tee "$vdir/backup.log") 2>&1 +if ! [ -d "$vdir" ]; then + echo $vdir does not exist >&2 + exit 1 +fi +if ps aux | \ + grep -v grep | \ + grep -E 'services.backups.rclone|local.ffprobe'; then + echo skipping colliding run >&2 + exit 0 +fi +echo ok at 1 +files=($(find $vdir -type f -name "*.m*")) +if [ "${#files[@]}" == "0" ]; then + echo no files found >&2 + exit 0 +fi +echo files=${files[@]} +includes=() +printf "reviewing"; printf " %s\n" "${files[@]}" +echo ok at 2 +for file in "${files[@]}"; do + frames="$( + nice -n 19 /var/services/homes/squeaky2x3/ffmpeg-local/ffprobe \ + -threads 1 -loglevel error -hide_banner -show_frames -of compact=p=0 \ + -f lavfi "movie=$file,select=gt(scene\\,$threshold)" 2> /dev/null \ + )" + ret=$? + if [ $ret -eq 0 ] && [ $(printf "%s\n" "$frames" | wc -l) -lt 2 ]; then + echo file has no movement $file >&2 + rm -f "$file" + elif [ $ret -ne 0 ]; then + echo failed scanning $file >&2 + files=("${files[@]/"$file"}") + else + echo file has movement $file + includes+=("$(basename "$file")") + fi +done +echo "pushing files ${includes[@]}" +if [ "${#includes[@]}" -gt 0 ]; then + if [ "$disabled" == "true" ] || \ + /volume1/homes/squeaky2x3/services/backups/rclone \ + --config /volume1/homes/squeaky2x3/services/backups/rclone.conf \ + copy \ + $vdir/ \ + blapointe-drive:/projects/cctv/ut/ \ + $(printf " --include %s" "${includes[@]}") ; then + rm -f "${files[@]}" + fi +fi +echo donezo +echo why diff --git a/testdata/record_rtsp_via_ffmpeg.sh b/testdata/record_rtsp_via_ffmpeg.sh new file mode 100755 index 0000000..f68bedc --- /dev/null +++ b/testdata/record_rtsp_via_ffmpeg.sh @@ -0,0 +1,117 @@ +#! /bin/bash + +SEG="${SEG:-300}" + +function main() { + if [ "$#" -eq 0 ]; then + log "USAGE: $0 ip ip ip..." >&2 + return 1 + fi + + function clean() { + kill -9 $(jobs -p) + } + if [ "$(hostname)" == "Scratch" ]; then + trap clean EXIT ERR + fi + watchman "$@" & + for ip in "$@"; do + log recording from $ip... + record "$ip" & + done + + for i in "$@"; do + if ! wait -n 1; then + log "Something died: $?" + exit 1 + fi + exit 0 + done +} + +function log() { + echo "$(date): $@" >&2 +} + +function mkdirs() { + mkdir -p "${OUT_DIR:-/tmp/ffmpeg_cap}/$(date +%Y)/$(date +%m)/$(date +%d)" +} + +function watchman() { + log watchman starting on $@ + local max_last=$SEG + max_last=$((max_last*3)) + function finder() { + local suffix="${1:-"*"}" + find "${OUT_DIR:-/tmp/ffmpeg_cap}" -type f -name "*_${suffix}.m*" + } + function mark_last_file() { + local now="$(date +%s)" + local suffix="$1" + local min=$((max_last-1)) + for f in $(finder "$suffix"); do + local ts="$(stat -c '%X' "$f")" + if ((now-tsmax_last)); then + log "no new videos in $seconds seconds for $suffix, panicking" + exit 1 + fi + done + until check_disk; do + local f="$(finder | sort | head -n 1)" + log "high disk usage, pruning $f" + rm -f "$f" + done + done +} + +function record() { + log "starting record for $@" + _record "$@" + tail -n 50 /tmp/ffmpegs.log +} + +function _record() { + local out="${OUT_DIR:-/tmp/ffmpeg_cap}/%Y/%m/%d/%H-%M-%S_${1}.mp4" + mkdirs + ffmpeg \ + -threads 0 \ + -nostdin \ + -nostats \ + -loglevel error \ + -i rtsp://192.168.0.$1:8554/unicast \ + -an \ + -map 0 \ + -force_key_frames "expr:gte(t,n_forced*9)" \ + -f segment \ + -segment_time $SEG \ + -segment_format mp4 \ + -strftime 1 \ + -minrate .05k \ + -vcodec copy \ + "$out" \ + -vf "select=gt(scene\,0.003),setpts=N/(15*TB)" \ + < /dev/null \ + >> /tmp/ffmpegs.log \ + 2>&1 +} + +if [ "$0" == "$BASH_SOURCE" ]; then + main "$@" +fi +