Trigger a USB-tethered camera for Cosmos timelapses instead of using the printer's built-in camera. Rendering is offloaded to a Linux desktop so the printer's R528 SoC doesn't have to do video encoding.
The printer fires a small HTTP call per layer to a Flask shim running on a Linux desktop. The shim calls gphoto2 to capture from the camera and saves the JPEG locally. At print end, ffmpeg renders the frames into an MP4.
printer (layer change) ──HTTP──▶ Flask shim ──▶ gphoto2 ──▶ camera (USB)
│
▼
JPEGs on desktop
│
▼
ffmpeg (at print end)
│
▼
MP4
- A printer running Cosmos
- A Debian (or Debian-based) Linux desktop on the same LAN (Probably works on others, Debian is all I know)
- A camera with USB control — anything supported by gphoto2 (most modern Sonys, Canons, Nikons, Fujis). Built and tested with a Sony a6000 in PC Remote mode.
- A dummy battery for the camera (long prints will drain a real battery)
sudo apt install python3-flask gphoto2 ffmpeg
mkdir -p ~/timelapses ~/tools/cosmosnap- Put
app.pyin~/tools/cosmosnap/ - Put
cosmosnap.servicein/etc/systemd/system/(Edit cosmosnap.service and replace USERNAME on theUser=andGroup=lines with your Linux username) sudo systemctl daemon-reload && sudo systemctl enable --now cosmosnap.service- On the camera: set USB Connection to PC Remote, switch to manual focus, set Auto Power Off to maximum
Smoke test:
curl "http://localhost:8090/snap?job=test"
ls ~/timelapses/test/A JPEG should land in that directory.
Append the contents of printer.cfg.snippet to the top of your printer.cfg (edit the hostname/IP to point at your desktop), then FIRMWARE_RESTART. Verify by running COSMOSNAP in the Mainsail console — it should produce another frame on the desktop under ~/timelapses/untitled/.
In your slicer's machine G-code:
- Change layer G-code:
COSMOSNAP - Machine end G-code:
RENDER_COSMOSNAP
Print normally. Frames accumulate in ~/timelapses/<job_name>/ on the desktop. When the print finishes, ffmpeg renders <job_name>.mp4 next to them — 1080p, ~10–20 MB for a typical 2-hour print, with a 3-second freeze on the last frame.
- GVFS will steal the camera on Debian with a desktop environment running — KDE/GNOME auto-mounts cameras as PTP storage. The systemd unit kills the gvfs camera processes on start, but if you plug the camera in after starting the service, run
sudo systemctl restart cosmosnap. - Manual focus is required. Autofocus will hunt on every shot and miss frames.
- Ensure your camera is set to take JPEG, not RAW photos
- MP4s land on the desktop, not in Mainsail's gallery.
app.py— Flask shimcosmosnap.service— systemd unitprinter.cfg.snippet— printer config blocks
The code was generated by Claude, but was reviewed and edited (to the best of my ability) by hand by me