#! /bin/bash set -eo pipefail if test -f /volume1/homes/squeaky2x3/services/moonfire-nvr.d/moonfire-nvr.sh; then bash /volume1/homes/squeaky2x3/services/moonfire-nvr.d/moonfire-nvr.sh fi main() { local nonrecent_unix="$(($(_date +%s) - 4 * 60 * 60))" # 4h ago local nonrecent_ts="$(_date -d @$nonrecent_unix -u +%Y-%m-%dT%H:%M:%SZ)" for uuid in $( api /api/ | jq -r .cameras[].uuid ); do local stream=main local recordings=($( api /api/cameras/$uuid/$stream/recordings \ | jq -c '.recordings[] | [.startId, .growing, .startTime90k]' \ | grep -v ,true, \ | jq -r .[0] \ | sort -n #-r )) for recording in "${recordings[@]}"; do if grep "^$uuid.$recording$" /tmp/movement_detection_via_api_ffmpeg.sh.txt; then continue fi local ts="$(_date -u -d @"$( api "/api/cameras/$uuid/$stream/view.mp4.txt?s=$recording&ts=true" \ | grep -A 1 last_modified: \ | head -n 2 \ | tail -n 1 \ | awk '{print $NF}' \ | tr -d ',' )" +%Y-%m-%dT%H:%M:%SZ )" if [ -z "$ts" ] || [[ "$ts" > "$nonrecent_ts" ]]; then echo "$ts > $nonrecent_ts, so skipping" continue fi echo uuid=$uuid stream=$stream recording=$recording ts=$ts api "/api/cameras/$uuid/$stream/view.mp4?s=$recording&ts=true" > /tmp/movement_detection_via_api_ffmpeg.sh.mp4 local fps=$(_ffprobe -i /tmp/movement_detection_via_api_ffmpeg.sh.mp4 2>&1 | grep -o '[0-9]*\.*[0-9]* fps' | head -n 1 | awk '{print $1}') local inspection="$(_ffmpeg -i /tmp/movement_detection_via_api_ffmpeg.sh.mp4 -vf 'select=not(mod(n\,'${fps%.*}')),select=gte(scene\,0),metadata=print:file=-' -an -f null - 2> /dev/null | paste - -)" local scores=($(echo "$inspection" | awk '{print $NF}' | sed 's/.*=//')) local flattened_scores=() for i in $(seq 1 ${#scores[@]}); do flattened_scores+=($(echo ${scores[@]:i-2:3} | tr ' ' '\n' | sort -n | head -n 2 | tail -n 1)) done local threshold=1 local last_n=(${flattened_scores[@]:0:7}) for i in $(seq 1 ${#flattened_scores[@]}); do last_n[$(( (i-1)%7 ))]=${flattened_scores[$((i-1))]} max_of_last_n=$(echo "${last_n[@]}" | tr ' ' '\n' | sort | tail -n 1) if [[ "$max_of_last_n" < "$threshold" ]]; then threshold="$max_of_last_n" fi done threshold="$(_perl -e "print $threshold + 0.005")" local has_change=false if [ "${#flattened_scores[@]}" -lt 10 ]; then has_change=true else local max_flattened_score=$(echo "${flattened_scores[@]:5:${#flattened_scores[@]}-10}" | tr ' ' '\n' | sort -n | tail -n 1) if [[ "${max_flattened_score#*.}" > "${threshold#*.}" ]]; then has_change=true fi fi if $has_change; then echo "$uuid.$recording" >> /tmp/movement_detection_via_api_ffmpeg.sh.txt else echo no movement in "$recording" echo api "/api/cameras/$uuid/$stream/view.mp4" \ -X DELETE \ -H 'Content-Type: application/json' \ -d "$(printf '{"runStartId": %s}' "$recording")" fi done done } api() { local path="$1" shift curl -sS "${CAMS_URL:-http://192.168.0.86:29898}/${path#/}" "$@" } _date() { if which gdate &> /dev/null; then gdate "$@" else date "$@" fi } _perl() { if which perl &> /dev/null; then perl "$@" else /var/services/homes/squeaky2x3/.nix-profile/bin/perl "$@" fi } _ffprobe() { if which ffprobe &> /dev/null; then ffprobe "$@" else /volume1/homes/squeaky2x3/ffmpeg-local/ffprobe "$@" fi } _ffmpeg() { if which ffmpeg &> /dev/null; then ffmpeg "$@" else /volume1/homes/squeaky2x3/ffmpeg-local/ffmpeg "$@" fi } main "$@"