moonfire-nvr is fire
parent
60c011278f
commit
5aad9c980d
|
|
@ -0,0 +1 @@
|
||||||
|
https://github.com/scottlamb/moonfire-nvr/blob/master/guide/install.md
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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-ts<min)); then
|
||||||
|
min=$((now-ts))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo $min
|
||||||
|
}
|
||||||
|
function check_disk() {
|
||||||
|
if du -s "${OUT_DIR:-/tmp/ffmpeg_cap}" | grep -E '^[6-9][0-9]{5}'; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
while sleep 10; do
|
||||||
|
mkdirs
|
||||||
|
for suffix in "$@"; do
|
||||||
|
local seconds=$(mark_last_file "$suffix")
|
||||||
|
log "$suffix: $seconds s"
|
||||||
|
if ((seconds>max_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
|
||||||
|
|
||||||
Loading…
Reference in New Issue