Another “Today I Learned”, except I was more “doing” than learning. Back in 2024 I was happy to find that the camera I invested in to monitor my kids doing homework back in the COVID days supported RTSP. I made a note to see if I can take it a bit farther, and if it wasn’t for the fact that the DCS-8526LH was eating Micro-SD cards and I was losing valuable information I wouldn’t be where I’m at now.
Enter the “Home DVR”…
Day One
I’m already running a home Linux Server with over 30tb of storage for Plex and other mundane tasks. I decided to see if I can push that again to constantly pull an RTSP stream from the camera and save the raw data on a timely basis, much like a DVR would.
A simple script on a cron was able to give me my 10-minute slices of time:
#!/bin/bash
ROOT="/mnt/usb14/Camera"
YEAR=`date +'%Y'`
MONTH=`date +'%m'`
DAY=`date +'%d'`
FULL=`date +'%Y%m%d-%H%M%S-%s'`
mkdir -p $ROOT/$YEAR/$MONTH/$DAY 2>/dev/null
# 10 minute stream
ffmpeg -i "rtsp://admin:658047@198.162.1.248:554/live/profile.0" -t 600 -c:v copy -c:a copy "$ROOT/$YEAR/$MONTH/$DAY/$FULL.mp4"
Set some variables, make some orderly folders, and use the -t 600
parameter to record for exactly 10 minutes.
Out of the box ffmpeg
comes with multiple way to scoop up whatever the input source is going to be, including RTSP with authentication params in the URL.
A simple crontab
later and now I’ve got a low CPU-usage process recording on-the-10th-minute videos to an organized folder.
# Streaming local cameras - 10m segments
*/10 * * * * cd /mnt/usb14/Camera && ./rtsp-recorder 2>&1 >/dev/null
Eventually i’ll have a tmpwatch
or something that’ll cull oldness or offload them to a long term storage. In the meantime this is more than I wanted, and I’m so happy I got my cheapo DVR for one camera. Next up, the ScamleySafe doorbell camera.
Day Two
Storage seemed to not be an issue at the start, but things slowly looked like they creeped up. Day two created about 13GB of raw video. I decided two things at this point
- Munge all the videos together and make one file
- See if I can compress it all down
Wrote a quick script that I kindly called “make-the-day”
#!/bin/bash
ROOT="/mnt/usb14/Camera"
if [ "$1" == "" ]; then
YEAR=`date -d'yesterday' +'%Y'`
MONTH=`date -d'yesterday' +'%m'`
DAY=`date -d'yesterday' +'%d'`
else
if [ "$2" == "" ]; then
echo "need 2nd parameter as month"
exit;
fi
if [ "$3" == "" ]; then
echo "need 3rd parameter as day"
exit;
fi
YEAR=$1
MONTH=$2
DAY=$3
fi
if [ ! -d $ROOT/$YEAR/$MONTH/$DAY ]; then
echo "folder $ROOT/$YEAR/$MONTH/$DAY does not exist"
exit
fi
find $ROOT/$YEAR/$MONTH/$DAY -type f -name '*.mp4' | sort > files
for LINE in `cat files`; do
echo "file '$LINE'" >> concat.txt
done;
rm files
if [ ! -e concat.txt ]; then
echo "concat file not made"
exit
fi
# make our one file for the day
ffmpeg -f concat -safe 0 -i concat.txt -c copy $ROOT/$YEAR/$MONTH/"$YEAR""$MONTH""$DAY".mp4
rm concat.txt
# Compress it down to whatever default x265 is. ~65% original size
if [ -e $ROOT/$YEAR/$MONTH/"$YEAR""$MONTH""$DAY".mp4 ]; then
ffmpeg -i $ROOT/$YEAR/$MONTH/"$YEAR""$MONTH""$DAY".mp4 -c:v libx265 -c:a copy $ROOT/$YEAR/$MONTH/"$YEAR""$MONTH""$DAY".x265.mp4
fi
if [ -e $ROOT/$YEAR/$MONTH/"$YEAR""$MONTH""$DAY".x265.mp4 ]; then
rm $ROOT/$YEAR/$MONTH/"$YEAR""$MONTH""$DAY".mp4
fi
TL;DR concatenate all the videos into one large one, then convert it to x265. If all was successful, then we clean up, otherwise leave all the junk everywhere and back to the drawing board.
I forced this script a bit after noonish everyday.
12 12 * * * cd /mnt/usb14/Camera && ./make-the-day 2>&1 >/dev/null