Project: Automated daily timelapse video using Linux and an old IP Webcam
Required- Intermediate Expertise: AND:
A Crappy Webcam, patience, Linux, Exiftool, wget, imagemagick, cron, ffmpeg knowledge, more patience,
BASH shell understanding
NOT for Beginners!
Resulting Video At End Of Page
I have an old IP Webcam Dlink DCS-930L from? 2012, able to resolve 640 x 480 pixels. I will not go into how I got this running on WiFi except to say I did start with an Ethernet connection : ) In so configuring, I did give it a Fixed IP Address on my local network of 192.168.1.22 which will come up later.
Using FireFox at http://192.168.1.22 you may get a still image AFTER filling in the Username/Password that you set up.
Chrome browser will not work as it wants to redirect to a Secure Site httpS://.. all the time which this camera is too Old to oblige.
Device is nearly useless now as it originally required Java and/orActiveX for video and other stuff, which is insecure and unused anymore, but, I did find from Other Hackers that you can grab a single JPG still image like so:
http://192.168.1.22/image/jpeg.cgi
Again, with Username And Password being required…
Started Thinking: If I use a CRON job to grab just such a frame every minute, we could have a nice time-lapse scripted Video every day, No?
So here is a script using WGET(WebGet) that grabs a jpeg frame from the camera every time it's called and saves it to a file: wget - http://192.168.1.22/image/jpeg.cgi \ --user=user --password=pass -O capture.jpg
Nice! Some tests showed that worked fairly reliably
More Cobbling with an ugly script- I have left in various pieces of diagnostic code for the curious. DO NOT run as Root User.
DO change the $BASE variable (the base directory to save files)
Script will generate date sequenced folders to drop timestamped jpg files a la:
/some/base/path/2021/Sep/01_Sat/13_15.jpg
I used a 24hr timestamp per file to simplify concatenation later and AVOIDED the use of colons which really throws stuff off:
script name I used: grabdlink
These paragraphs are ALL ONE SCRIPT which maintain variable names throughout. Note the $BASE path must be writable by the CRON owner and happens to be where the Web Server expects to find content in many distributions (Mine is MINT 20)
any number of directories off the ‘parent’ will be created as needed
which is the the -p arg in “mkdir”
______________________________________________
#!/bin/bash YEAR=`date +%Y` # 4 digit year MONTH=`date +%b` # Full Month name DATE=`date +%d` # 01-31 day DAY=`date +%a` # 3 char Day of Week # TIME=`date +%I`_`date +%M`_`date +%p` # CLOCK=`date +%R` # R=24h Clock 21:23 HR=`date +%H_%M` # BASE="/var/www/html/dlink" FOLDER="$YEAR/$MONTH/$DATE"_"$DAY" FILE="$HR" # FULLPATH="$BASE/$FOLDER/$FILE.jpg" mkdir -v -m 0755 -p $BASE/$FOLDER # echo "OutPut Name: " $BASE/$FILE.jpg wget - http://192.168.1.22/image/jpeg.cgi --user=user --password=pass -O $FULLPATH
#__________________________________________ #The Dlink Camera produces basic JPEG files that lack any #meaningful EXIF (embedded meta data) so I added my own using #the superb EXIFTOOL (All One Line below... sorry!) #______________________________________________ /usr/bin/exiftool -P -overwrite_original '-AllDates<FileModifyDate' '-Model=Dlink DCS‑930L IPCAM' '[email protected]' '-Description=Http://Www.ArtOfLogic.Com' "-Comment=Http://Www.ArtOfLogic.Com Technology" $FULLPATH #___________________________________________ #This way at least the time stamp for the #original shot remains #within the image no #matter what happens to the file's Unix # # #timetamp(s)! #Now lets use the magical IMAGEMAGICK tools to #embed a visible #imestamp inside each jpg image. #It uses the embedded timestamp #we just created #so will work no matter how the *nix file time #stamps change later: __________________________________________________ convert "$FULLPATH" -gravity SouthEast -pointsize 20 -fill blue -annotate +30+30 %[exif:DateTimeOriginal] "$FULLPATH"; #END OF SCRIPT grabdlink
___________________________________________
Run as a Cron job:
* 6-18 * * * /home/sysop/bin/grabdlink
This will run every 60 seconds between 6AM and 7PM, not 6PM
as it’s all the times where “18” matches the hr position : ))
This will give us about 900 jpg images per day one per minute all inside one day dated folder. Nice.
At some point past the last capture (Or even during them, Why Not)
you can run this rather nasty-looking ffmpeg script to make things into a nice h.264 Video WITH AUDIO!.
Note that “GotamaCut.m4a” is an aac encoded Audio File longer than the longest expected video production, which will be copied into the resulting image stream, but will STOP as soon as the full video has played out.Ugly cut off ending, but it works
If you remove the “-shortest” option , audio will keep playing to its end while showing the last frame frozen. Could Do That Eh?
Also- ffmpeg DOES have a Fade Out option for audio add-in,
But I did not use it ; )
The mysterious TOUCH command sets the earliest time stamp possible for the resulting video so it will sort at the TOP of listings on an auto indexed web page. Of course, you can get cleverer than me here and fix it to the Earliest Still’s Date. Your Exercise!
_________________________________________
ffmpeg -i /home/sysop/Music/GotamaCut.m4a \
-r 8 -pattern_type glob -i ‘*.jpg’ \
-map 0:a -map 1:v -shortest -c:a copy -c:v libx264 -crf 25 -pix_fmt yuv420p timelapse_h264.mp4
# make It Sort FIRST (Earliest!) in Web listings
touch -t 202001010000 timelapse_h264.mp4
# End.
________________________________________
You COULD use libx265 not libx264 for an even more squashed HEVC video BUT web pages using HTML5 do not (yet) seem to know how to handle these. VLC is fine about it though : )
Likewise: -pix_fmt yuv420p seems to be required so web pages can stream the resulting video. I do not pretend to know Why : )
There IS a format MJPEG that means, “Motion Jpeg” but this is inefficient as it cannot perform intra-frame Compression,
only inter image. Lots of room to experiment!
-r 8 represents the “rate” of Frames per Second
Do the Math : )
Aaaand here is the Resulting Video
_______________________________________