Technical details
The OctoCam stack is a doozy! I can't write all about it here, but I'll do my best to give a short summary. If you're still curious after reading (or just prefer images), be sure to check out the
image version of the detailed OctoCam stack. This stack is a bit outdated (and doesn't include newer changes to the networking in my apartment + long-term video storage), but gives a decent overview of how it all works.
The OctoCam stack is divided into three layers - the OctoCam Pi that's actually stuck to the window capturing images, the backend which does image storage/video encoding, and the frontend which does video storage and actually serves the frontend. There's a split between the backend and frontend as my web VPS does not have the storage for storing all of OctoCam's images nor the CPU power to encode OctoCam videos. Thankfully, the "server" (it's an Optiplex 3060 from eBay) in my apartment has a lot of "CPU power" (as much as an i5-8500 has...but much more than my VPS) and disk space! But it's also on a residental asymmetric connection with measly upload speeds - not great for serving video. As such, the backend uploads videos for the frontend for storage. That's a very high level summary of the stack though, the image has A LOT more detail.
In terms of image capture, OctoCam is currently using the Raspberry Pi Camera Module 3 since June 2024, a Sony IMX708 with a ~70 degree FoV. Images are captured at 1296x2304 using the Picamera2 library. Focus is set to infinity at night, and during the day is refocused every 20 minutes.
OctoCam has gone through three other cameras (and four resolutions) throughout its lifetime, including:
- - Raspberry Pi Camera Module 3 at 2304x1296 in June 2024
- - Raspberry Pi Camera Module 3 Wide from June 2023 to June 2024 (2304x1296)
- - Omnivision OV5647 at 120 degree FoV from May 2021 to June 2023 (1600x1200)
- - Omnivision OV5647 at ~80 degree FoV from March 2021 to May 2021 (1600x1200)
OctoCam usually captures in full auto during the day, but has special logic to go into a custom night mode with longer, fixed shutter speeds. Night mode runs from just a bit before sunrise to just a bit after sunrise. The timing of night mode is complicated, especially since OctoCam includes checks to see how cloudy it is at sunrise and sunset, and can defer coming out of night mode for longer or go into night mode earlier.
The current night mode exposure time is 125ms in transition night mode (mainly for preventing over-exposures just before/after the sun crosses the horizon), and 250ms in full night mode. Previously, the exposure time was 500ms and 1000ms respectively with the CM3 Wide in Worcester, and 1000ms and 2000ms respectively on the OV5641 cameras.
OctoCam encodes videos at 8 Mbps @ CRF 25 using ffmpeg (previously at 6 Mbps with the OV5647 cameras). There's some compatibility flags so hopefully videos play across as many browsers as possible.
OctoCam is largely coded in Python. The entire Pi-side and backend is done in Python. Both the backend and frontend use Flask as a web server. The frontend also uses Jinja2 server-side rendering for a good chunk of pages (the homepage now uses a lot of client-side rendering to keep things up-to-date however).