Live frames were visible at /plantcam. Check back later for new plants!
The camera is a raspberry pi “noir” camera v2. Sensor data is captured using a BME280 sensor.
Capture
I’m using raspistill
to capture the photos. It’s adding an annotation (with some metrics from a BME280 environment sensor) on top of the image. This runs every half-hour using a cron-job.
raspistill \
-ae 70,0xff,0x808000 \
-a 1024 \
-a " PlantCam 'Basil' - $(date) \n $(temp-metrics.sh) " \
-e jpg \
-th none \
-o "timelapse/plant-$(date +'%Y-%m-%d_%H_%M_%S').jpg"
Low Quality Capture
This variant with reduced quality is run every minute and is used for the live photo.
raspistill \
-ae 20,0xff,0x808000 \
-a 1024 \
-a " PlantCam 'Basil' - $(date) \n $(temp-metrics.sh) " \
-w 640 \
-h 480 \
-q 60 \
-e jpg \
-th none \
-o latest.jpg
Compile Timelapse to Video
To compile the frames into an mp4
video, I’m combining some info from my previous post about using ffmpeg, with a trick to easily grab all the photos using a glob:
ffmpeg \
-y \ # Always overwrite
-f image2 \ # Force input type to image2
-pattern_type glob \ # Use input pattern as a glob
-i 'timelapse/*.jpg' \ # Glob all the files
-vcodec libx264 \ # Use the h264 video codec
-pix_fmt yuv420p \ # Apple Quicktime support
-profile:v baseline \ # For compatibility
-level 3 \
-movflags faststart \ # <- move the moov atom
timelapse/output.mp4
The resulting video is served on a hidden web server and then served to end users via CloudFront.
Cache Control
I’m setting Cache-Control: max-age=<duration>
on my nginx server to ensure cloudfront doesn’t cache images & videos too long. The duration (seconds) is set to the interval of each script.
Camera Setup
The camera is secured to the lightbar using some velcro cable ties, and the bottom half of one of these camera mounts.