cctv/testdata/record_rtsp_via_ffmpeg.sh

118 lines
2.5 KiB
Bash
Executable File

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