DIY Camera Timelapse für NanoDLP und einer IP Camera
Ich hab ein altes Android Smartphone mit der App IP Camera von Pavel Khlebovich zu einer Webcam gemacht. Diese kann man dann einfach mit einem Get request ansprechen um ein Foto zu speichern. Das funktioniert nicht nur mit Octoprint (z.B. mit Octolapse), sondern auch mit NanoDLP.
Wir können uns also ein Bash Script schreiben, welches wir von NanoDLPs Camera Schnittstelle aufrufen lassen, z.B. bei jedem Ebenenwechsel. Danach brauchen wir ein Script welches uns aus den Frames ein Video rendert. Wir können dann auch die Frames wieder löschen oder irgendwo auf ein Netzwerk-Ordner verschieben.
Inhalt
Fotos speichern:
WIr öffnen also zunächst die Console / das Terminal in Windows und öffnen eine ssh Verbindung zu unserem RaspberryPi im 3D-Drucker, auf dem NanoDLP läuft. Benutzer ist pi und das Standardpasswort „raspberry“ wird verwendet, sofern ihr es nicht geändert habt.
ssh pi192.168.178.XX
Nun müssen wir uns einen Ort in der Ordnerstruktur suchen, an dem wir die Frames speichern möchten. Ich hab mich hier für Media entschieden. Mit cd können wir an den gewünschten Ort springen.
cd media #navigate to folder
Dann können wir ein neues Verzeichnis für unsere Timelapses anlegen. Dieses müssen wir mit den entsprechenden rechten (lesen, schreiben, ausführen) ausstatten.
sudo mkdir timelapse
sudo chmod 777 timelapse
Bash Script
Wir gehen in den neuen Unterordner mit:
cd timelapse
Nun erstellen wir mit dem Texteditor nano eine neue .sh Datei. Das ist ein bash Script, welches wir später ausführen.
sudo nano timelapse.sh
Im dem neu geöffneten Editorfenster (im Terminal) kopieren wir den folgenden Code. Dieser startet einen wget mit einem Pfad prefix -p und speichert dann das Bild von der Webcam URL. Da hier der lenght header nicht stimmt, müssen wir diesen ignorieren.
Danach nutzen wir den mv Befehl (move) um die Datei umzubennen. Ihr könntet die Frames damit auch in einen Unterordner „Frames“ verschieben, falls gewünscht. mit dem $(date …) Befehl wird das Datum und die Uhrzeit hinzugefügt. Damit sind die Snapshots dann auch in der richtigen Reihenfolge zum rendern.
#!/bin/bash
wget -P /media/timelapse http://192.168.178.70:8080/photo.jpg --ignore-length #path to store file and ip-camera snapshot path
mv /media/timelapse/photo.jpg /media/timelapse/timelapse$(date +%m%d%Y-%H%M%S).jpg #using mv command to rename file
Damit wir das bashscript ausführen können, müssen wir wieder die Rechte zuweisen.
sudo chmod +x timelapse.sh
In der nanoDLP Weboberfläche können wir dann den code zum ausführen des Scriptes einfügen. Dies finden wir unter Settings – Maschine Settings – Camera.
sh /media/timelapse/timelapse.sh
Test
Wir können z.B. auf nur manuelle Auslösung gehen und den Button „Take Photo“ drücken, oder wir feuern das Script einmal im Terminal.
Wenn wir dann im Ordner timelapse nachschauen, sollte dort ein Bild zu finden sein.
ls
Dies können wir uns auch Ansehen. Dazu gibt es mehrere Wege. Das hier soll aber Noob Freundlich sein, daher nehmen wir einfach mal einen FTP Client wie FileZilla zur Hand. Wir verbinden per sftp protokoll zur IP des NanoDLP Raspberrypi, user und Passwort sind ja aus der ssh verbindung bekannt, der Port ist 22.
Dann können wir in die entsprechende Ordnerstruktur navigieren, wo das Bild liegt.
Mit drag&drop können wir das auf den desktop ziehen und ablegen und uns anschauen. Siehe da: Wir sehen den Drucker 🙂
Ich nutze einen Kudo3D Bean von Kickstarter und mein selbst eingepasstes VAT.
Timelapse Rendern
Hier bin ich bei der Recherche auf das Tutorial von „phamthanhnam“ im Raspi-Forum gestoßen und habe das einfach mal ausprobiert, da er die hohe geschwindigkeit des GPU rendern lobt. Ich beschreibe hier einfach das gleiche wie im Forum, nur halt etwas angepasst für diese Anwendung.
Es gibt aber auch noch andere Methoden das Video aus den Frames zu rendern. Die Keywords wären: mencoder, ffmpeg, avconv
Wir schreiben uns ein zweites Bash-Script um verschiedene Dienste der Reihe nach aufzurufen. Erstmal müssen wir die Bilder umbenennen, da ich erstens nicht hinbekommen hab mit den komplizierten Dateinamen und zweitens, weil der Encoder keine Lücken in der Nummerierung mag. Dazu nutzen wir das GAWK Paket.
Dann müssen wir aus NanoDLP den aktuellen Status herauskriegen. Dazu nutzen wir einfach cURL. Hier bekommt man allerdings ein JSON zurück, welches wir mit dem Tool jq einfach parsen können. Wenn der Status quasi fertig ist (ihr merkt, das ist bei mir ganz schöner pfusch) dann rufen wir erst den Renderer auf. Dieser Teil wird in der Vorhandenen timelapse.sh ergänzt. Aber zuerst müssen wir mal schauen das alles up-to-date ist.
sudo apt-get update
sudo apt-get upgrade
Bei meinem NanoDLP ist das Raspian darunter schon etwas outdated, daher kam eine Fehlermeldung beim Versuch es upzudaten.
Sollte das bei euch auch der Fall sein, nutzt einfach den folgenden Zusatz.
sudo apt-get update --allow-releaseinfo-change
Jetzt können wir wie gewohnt auf den neuesten Stand upgraden:
sudo apt-get upgrade
Auf seiner Domain stellt Pham die nötige Software bereit. Wir können die Quelle hinzufügen und dann die Pakete installieren. Am Ende prüfen wir ob alles geklappt hat.
sudo sh -c 'echo deb http://vontaene.de/raspbian-updates/ . main >> /etc/apt/sources.list'
sudo apt-get update
sudo apt-get install libgstreamer1.0-0 liborc-0.4-0 gir1.2-gst-plugins-base-1.0 gir1.2-gstreamer-1.0 gstreamer1.0-alsa gstreamer1.0-omx gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-pulseaudio gstreamer1.0-tools gstreamer1.0-x libgstreamer-plugins-bad1.0-0 libgstreamer-plugins-base1.0-0
gst-inspect-1.0 | grep omx
Dann können wir GAWK installieren. Das stellt später sicher dass wir eine durchgängige Nummerierung haben, damit das Encoding auch funktioniert.
sudo apt-get install gawk
Außerdem brauchen wir jq um den JSON-String zu parsen. Da kam bei mir irgendwas als Fehlermeldung, hat aber trotzdem Installiert.
sudo apt-get install jq
Ihr solltet jetzt ja immernoch im Ordner timelapse in der Dateistruktur sein. Falls nicht, können wir das sicherstellen mit:
cd ~
cd /media/timelapse
Jetzt erstellen wir das render Bashscript:
sudo nano render.sh
Das füllen wir mit dem folgenden Code:
#!/bin/bash
day=$(date +%m-%d-%Y)
relative=/media/timelapse
echo "renaming files to be in order"
find -name '*.jpg' | gawk 'BEGIN{ a=0 }{ printf "mv %s $relative/$day/frames/timelapse-%06d.jpg\n", $0, a++ }' | bash
echo "Now converting video (This may take a few minutes...)"
gst-launch-1.0 multifilesrc location=$relative/$day/frames/timelapse-%06d.jpeg index=1 caps="image/jpeg,framerate=24/1" ! jpegdec$echo "Conversion complete"
echo
echo
echo "Cleaning up...."
sudo rm -rf $relative/$day/frames/
clear
echo "Your timelapse video is ready! You may view your video at $relative/$day/"
echo
Erläuterung
day=$(date +%m-%d-%Y) – Speichert uns das heutige Datum in eine Variable namens Day.
relative=... Das ist der Pfad wo wir uns arbeiten. Spart etwas getippe
echo „…“ gibt uns den Text als Rückmeldung im Terminal
find – name *.jpg sucht im Ordner nach allen Daten vom typ .jpg
| gawk sorgt dafür, dass die ergebnisse der reihe nach mit gawk behandelt werden. Der rest ist fürs umbennen zuständig
gst-launch … ist die Encoding-Engine
Dann gibt es ein paar Rückmeldungen und am ende können wir die Frames löschen um Speicherplatz zu sparen.
Wir speichern mit strg+o und verlassen mit strg+x. Dann müssen wir die Datei ausführbar machen:
sudo chmod +x render.sh
Nun können wir uns noch einmal die timelapse.sh vornehmen
sudo nano timelapse.sh
Diese müssen wir wie folgt anpassen:
#!/bin/bash
day=$(date +%m-%d-%Y)
relative=/media/timelapse
echo "creating folder for today"
mkdir $relative/$day/
mkdir $relative/$day/frames/
echo "getting snapshot"
wget -P $relative/$day/frames http://192.168.178.70:8080/photo.jpg --ignore-length -c -q
mv $relative/$day/frames/photo.jpg $relative/$day/frames/timelapse$(date +-%H%M%S).jpg #using mv command to rename file
sync
status=$(curl 192.168.178.68/status | jq .Printing)
echo $status
echo "Printer Status: "
if $status == true
then
echo "still printing"
else
echo "printing seems to be done, rendering video"
sh $relative/render.sh
fi
Erläuterung
day=$(date +%m-%d-%Y) – Speichert uns das heutige Datum in eine Variable namens Day.
relative=... Das ist der Pfad wo wir uns arbeiten. Spart etwas getippe
echo „…“ gibt uns den Text als Rückmeldung im Terminal
mkdir erstellt den Ordner (make directory)
wget holt sich den Snapshot (gleich wie vorher, nur Pfad ist neu)
mv nennt die Datei um (gleich wie vorher, nur Pfad ist neu)
sync soll sicherstellen, das nix verloren geht.
status = curl … wir speichern die Response von curl in die Variable status
| jq .Printing Parsed die JSON Antwort vom Curl und sorgt dafür, dass nur der Inhalt von Printing in status gespeichert wird. (Status ist also nur true oder false, nicht das gesamte JSON-Objekt)
if … Hier prüfen wir ob status true oder false ist und rufen entsprechend das neue render.sh Script auf.
Wir könnten uns jetzt noch eine Sicherheitslogik einbauen, in dem wir eine IF für eine Fehlerhafte Rückmeldung von der IP-Camera einbauen.
Zusammenfassung
Wenn alles geklappt hat, könnt ihr jetzt coole Timelapse Videos von euren SLA 3D Drucken mit NanoDLP erstellen. Pretty Cool!
Ich parke die beiden Scripte auch auf Github 🙂
Happy Printing!
Update 31.03.2023 – FFMPEG
Ich habe nun auf ffmpeg umgestellt, da mir irgendwas mein nanodlp zerschossen hatte und ich neu installieren musste. Die Files vom vorherigen Render Ansatz sind ja auch in die Jahre gekommen und ffmpeg ist einfach DER Standard. Nun hab ich mal wieder alles auf dem aktuellsten Stand.
Installieren von ffmpeg
ffmpeg installieren wir mit:
sudo apt install ffmpeg
wir editieren wieder mit nano unser render bashscript welches nun wie folgt lautet:
#!/bin/bash
day=$(date +%m-%d-%Y)
relative=/media/timelapse
echo "renaming files to be in order"
cd $relative/$day/frames
find . -name '*.jpg'| sort -n | gawk 'BEGIN{ a=0 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
echo "Now converting video (This may take a few minutes...)"
ffmpeg -r 24 -i %04d.jpg -s:v 1920x1080 -c:v libx264 timelapse-$day.mp4
mv timelapse-$day.mp4 $relative/$day
#echo "Cleaning up...."
#sudo rm -rf $relative/$day/frames/
#clear
echo "Your timelapse video is ready! You may view your video at" $relative/$day/
Ich hoffe das funktioniert bei euch auch so wie bei mir 🙂
Die einzige neue Zeile ist btw:
$ffmpeg -r 24 -i $relative/$day/frames/%04d.jpg -s:v 1920x1080 -c:v libx264 timelapse-$day.mp4
-r Framerate
-i input quelle
-s Auflösung
-c codec
Happy Timelapsing!
$ Die mit einem $ gekennzeichneten Links, sind Affiliate Links. Wenn du über diese in den Shop gelangst und etwas kaufst, bekomme ich eine kleine Provision
1 Kommentar
[…] Wie ihr NanoDLPs Infos in HomeAssistant einlest, gibt es ja schon hier.Die URL für den Status nutze ich dann auch für das Rendern des Videos im Timelapse Script. […]