#!/bin/bash set -e DIR="$( cd "$( dirname "$(realpath "${BASH_SOURCE[0]}")" )" &>/dev/null && pwd )" PROGNAME="$0" . "$DIR/lib.bash" curl_opts="-s --connect-timeout 5 --retry 5 --max-time 10 --retry-delay 0 --retry-max-time 40" allow_multiple= config_file="$HOME/.config/ipcam_motion_worker/config.txt" declare -A config=() usage() { cat </dev/null || die "failed to change to ${config[fs_root]}" touch tmp || die "directory '${config[fs_root]}' is not writable" rm tmp [ -f "video.mp4" ] && { echowarn "video.mp4 already exists in ${config[fs_root]}, removing.." rm "video.mp4" } while read line; do words=($line) file=${words[0]} size=${words[1]} if (( size > config[fs_max_filesize] )); then echoerr "won't download $file, size exceedes fs_max_filesize ($size > ${config[fs_max_filesize]})" report_failure "$file" "too large file" continue fi url="${config[api_url]}/api/recordings/${config[camera]}/download/${file}" debug "downloading $url..." if ! download "$url" "video.mp4"; then echoerr "failed to download $file" report_failure "$file" "download error" continue fi tc=$(do_motion "video.mp4") debug "$file: timecodes=$tc" report_timecodes "$file" "$tc" rm "video.mp4" done < <(get_recordings_list) popd >/dev/null } do_motion() { local input="$1" local roi_file="$(get_roi_file)" local tc local timecodes=() time_start if [ -z "$roi_file" ]; then timecodes+=($(do_dvr_scan "$input")) else echoinfo "using roi sets from file: ${BOLD}$roi_file" while read line; do if ! [[ "$line" =~ ^#.* ]]; then tc="$(do_dvr_scan "$input" "$line")" if [ -n "$tc" ]; then timecodes+=("$tc") fi fi done < <(cat "$roi_file") fi debug "do_motion: finished in $(time_elapsed)s" timecodes="$(echo "${timecodes[@]}" | sed 's/ */ /g' | xargs)" timecodes="${timecodes// /,}" echo "$timecodes" } dvr_scan() { "${config[dvr_scan_path]}" "$@" } do_dvr_scan() { local input="$1" local args= if [ ! -z "$2" ]; then args="-roi $2" echoinfo "dvr_scan(${BOLD}${input}${RST}${CYAN}): roi=($2), mt=${config[threshold]}" else echoinfo "dvr_scan(${BOLD}${input}${RST}${CYAN}): no roi, mt=${config[threshold]}" fi dvr_scan -q -i "$input" -so \ --min-event-length ${config[min_event_length]} \ -df ${config[downscale_factor]} \ --frame-skip ${config[frame_skip]} \ -t ${config[threshold]} $args | tail -1 } [[ $# -lt 1 ]] && usage while [[ $# -gt 0 ]]; do case $1 in -c|--config) config_file="$2" shift; shift ;; --allow-multiple) allow_multiple=1 shift ;; -v) VERBOSE=1 shift ;; -vx) VERBOSE=1 set -x shift ;; *) die "unrecognized argument '$1'" exit 1 ;; esac done if [ -z "$allow_multiple" ] && pidof -o %PPID -x "$(basename "${BASH_SOURCE[0]}")" >/dev/null; then die "process already running" fi read_config "$config_file" config check_config config "api_url camera" if [ -n "${config[remote]}" ]; then check_config config "fs_root fs_max_filesize" fi [ -z "${config[threshold]}" ] && config[threshold]=1 [ -z "${conifg[min_event_length]}" ] && config[min_event_length]="3s" [ -z "${conifg[frame_skip]}" ] && config[frame_skip]=2 [ -z "${conifg[downscale_factor]}" ] && config[downscale_factor]=3 [ -z "${conifg[dvr_scan_path]}" ] && config[dvr_scan_path]="dvr-scan" if [ -z "${config[remote]}" ]; then process_local else process_remote fi