ipcam-record.sh raw
1 #!/bin/bash
2 # Persistent multi-camera capture with zero-gap segmentation
3 # Condenses each completed segment automatically
4 # Usage: ipcam-record.sh [cameras.conf]
5 CONF="${1:-$(dirname "$0")/ipcam-cameras.conf}"
6 DIR="$HOME/Downloads/ipcam"
7 SEGMENT=600
8 PIDFILE="$DIR/.capture.pids"
9 CONDENSE="$(dirname "$0")/ipcam-condense.sh"
10 MERGE="$(dirname "$0")/ipcam-merge.sh"
11
12 mkdir -p "$DIR"
13
14 cleanup() {
15 if [ -f "$PIDFILE" ]; then
16 while read pid; do
17 kill "$pid" 2>/dev/null
18 done < "$PIDFILE"
19 rm "$PIDFILE"
20 fi
21 exit 0
22 }
23 trap cleanup INT TERM
24
25 > "$PIDFILE"
26
27 # launch one ffmpeg per camera
28 while read -r name url; do
29 [ -z "$name" ] && continue
30 [[ "$name" == \#* ]] && continue
31
32 (
33 while true; do
34 ffmpeg -loglevel error \
35 -vaapi_device /dev/dri/renderD128 \
36 -i "$url" \
37 -vf "drawtext=text='%{localtime\:%Y-%m-%d %T %Z}':fontsize=28:fontcolor=white:borderw=2:bordercolor=black:x=24:y=h-48,format=nv12,hwupload" \
38 -c:v h264_vaapi -qp 18 \
39 -f segment \
40 -segment_time "$SEGMENT" \
41 -segment_format matroska \
42 -reset_timestamps 1 \
43 -strftime 1 \
44 -segment_list pipe:1 \
45 -segment_list_type flat \
46 "$DIR/${name}_%Y%m%d_%H%M%S.mkv" \
47 </dev/null 2>/dev/null |
48 while read -r completed; do
49 [ -z "$completed" ] && continue
50 # segment_list outputs bare filename, add dir
51 f="$DIR/$completed"
52 [ -f "$f" ] || continue
53 echo "segment complete: $completed, condensing..."
54 bash "$CONDENSE" "$f" && bash "$MERGE"
55 done
56 # if ffmpeg dies (camera offline), retry after 5s
57 sleep 5
58 done
59 ) &
60 echo $! >> "$PIDFILE"
61 echo "started capture: $name ($url) pid=$!"
62
63 done < "$CONF"
64
65 echo "all cameras started, waiting..."
66 wait
67