#! /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