Ich habe bereits seit einigen Wochen immer wieder über den Eigenbau einer Überwachungskameralösung nachgedacht...
Zunächst begann ich sehr klein: Ich benutzte eine vorhandene USB-WebCam und versuchte zunächst , daraus einen Videostrom zu erzeugen, den ich auf einem anderen Rechner weiterverarbeiten könnte. Nach einigen Fehlschlägen und Sackgassen war ich schließlich so weit, einen solchen mittels eines selbst kompilierten ffmpeg zu versenden und an einem anderen Rechner zu konsumieren.
Ich suchte dann weiter nach anderen Lösungen und fand ustreamer: Das sah wirklich vielversprechend aus: Die Hardwarebeschleunigung des Raspi wurde voll genutzt. Allerdings stellte sich nach etwas über einer Stunde heraus, dass die Anwendung wohl doch nicht so stabil war, wie man es sich wünschen würde: Die Anwendung beendete sich. Systematische Tests ergaben, dass dieses Phänomen (bei mir) immer nach ungefähr einer Stunde auftrat. Also eher nicht so geeignet für eine Lösung, die eigentlich dafür vorgesehen war, mehrere Stunden oder sogar Tage am Stück zu funktionieren.
Weitere Recherchen machten mich auf mediamtx aufmerksam - und hier schien ich nun eine funktionierende Alternative gefunden zu haben. Daher bestellte ich mir jetzt auch eine echte Raspi-Kamera und in der Zeit, in der ich auf die Lieferung warten musste probierte ich die mir von meinem Kollegen ans Herz gelegte Lösung MotionOS bzw. MotionEye aus. Die Ergebnisse waren vielversprechend und ich wartete voller Ungeduld auf die neue Kamera.
Die Inbetriebnahme mit mediamtx gestaltete sich problemlos. Ich startete den TEst um 12:00 mittags mit einer Powerbank zur Stromversorgung, die zu 100% geladen war. Ich nutzte eine Auflösung von 720p und eine Bildrate von 10 Hz. Die Auslastung des Raspi Zero W war ohne Clients für den Strom bei 50%, mit einem Client lag sie um 80%. Den Stream konsumierte ich zu Beginn des Tests noch mit ffplay - später dann mit MotionEye.
Nach etwas mehr als einer Stunde wurde der Stream sehr schnell kontinuierlich schlechter - weder ein Neustart des Servers noch des Clients halfen hier weiter... Der Client beschwerte sich über den Stream wie folgt:
[h264 @ 0x79f46c404e40] error while decoding MB 9 24, bytestream -19
[h264 @ 0x79f46c404e40] concealing 1720 DC, 1720 AC, 1720 MV errors in P frame
[h264 @ 0x79f46c381680] error while decoding MB 32 20, bytestream -11
[h264 @ 0x79f46c381680] concealing 2017 DC, 2017 AC, 2017 MV errors in P frame
[h264 @ 0x79f46c287dc0] error while decoding MB 12 4, bytestream -21
[h264 @ 0x79f46c287dc0] concealing 3317 DC, 3317 AC, 3317 MV errors in P frame
[h264 @ 0x79f46c37bec0] error while decoding MB 33 42, bytestream -9
[h264 @ 0x79f46c37bec0] concealing 256 DC, 256 AC, 256 MV errors in P frame
[h264 @ 0x79f46c404e40] error while decoding MB 3 6, bytestream -5
[h264 @ 0x79f46c404e40] concealing 3166 DC, 3166 AC, 3166 MV errors in P frame
[h264 @ 0x79f46c381680] error while decoding MB 39 16, bytestream -39
[h264 @ 0x79f46c381680] concealing 2330 DC, 2330 AC, 2330 MV errors in I frame
[h264 @ 0x79f46c287dc0] error while decoding MB 9 13, bytestream -7
[h264 @ 0x79f46c287dc0] concealing 2600 DC, 2600 AC, 2600 MV errors in P frame
[h264 @ 0x79f46c0ce480] error while decoding MB 18 7, bytestream -5
[h264 @ 0x79f46c0ce480] concealing 3071 DC, 3071 AC, 3071 MV errors in P frame
[h264 @ 0x79f46c404e40] concealing 58 DC, 58 AC, 58 MV errors in P frame
[h264 @ 0x79f46c418d00] error while decoding MB 3 42, bytestream -9
[h264 @ 0x79f46c418d00] concealing 286 DC, 286 AC, 286 MV errors in P frame
[h264 @ 0x79f46c287dc0] error while decoding MB 10 3, bytestream -9
[h264 @ 0x79f46c287dc0] concealing 3399 DC, 3399 AC, 3399 MV errors in P frame
[h264 @ 0x79f46c404e40] error while decoding MB 53 1, bytestream -13
[h264 @ 0x79f46c404e40] concealing 3516 DC, 3516 AC, 3516 MV errors in P frame
[h264 @ 0x79f46c381680] error while decoding MB 68 13, bytestream -13
[h264 @ 0x79f46c381680] concealing 2541 DC, 2541 AC, 2541 MV errors in P frame
[h264 @ 0x79f46c287dc0] error while decoding MB 10 4, bytestream -20
[h264 @ 0x79f46c287dc0] concealing 3319 DC, 3319 AC, 3319 MV errors in P frame
Meine Arbeitshypothese - da ich Raspi und Kamera in das offizielle Gehäuse gequetscht hatte - war, dass die Temperatur einfach zu hoch war. Daher baute ich alles wieder auseinander und startete das Experiment nach einer Stunde Cooldown erneut. Der Stream war nach diesem Neustart wieder ok und blieb es auch. Beim Abbruch des Experiments zum Umbau betrug der Ladestand der Powerbank übrigens 96%.
Der Neustart erfolgte um 14:52, um 15:27 stellte ich eine Prozessorlast von annähernd 100% fest - da sich an der Qualität des Streams aber nichts geändert hatte, setzte ich das Experiment fort. Am nächsten Morgen um 7:00 prüfte ich den Stream - immer noch OK - und die Prozessorlast - wenig über 90% - wie auch den Status der Powerbank; immer noch zu 63% gefüllt.
Zu diesem Zeitpunkt (und um die Bewegungserkennung von MotionEye zu testen) änerte ich den Aufstellort der Kamera ohne das Experiment zu unterbrechen. Vergleichend konnte ich übrigens feststellen, dass die Raspi-Kamera nicht einen so großen Blickwinkel aufwies wie die USB-Kamera, mit der ich diese Reise begonnen hatte. Nach einigen Stunden verlagerte ich nochmals den Aufstellort - wegen meines sehr fragilen freitragenden Testaufbaus schaltete sich der Raspi währenddessen jedoch ab. So konnte ich gleich testen, wie MotionEye auf das Verlieren von Streams reagiert: Nachdem ich den Raspi neu gestartet hatte, benutzte MotionEye den Stream einfach weiter, sobald erwieder verfügbar war - ich musste nicht eingreifen.
Nachdem mein Experiment 24 Stunden gelaufen war stellte ich in der Powerbank eine verbleibende Ladung von 52 % fest - allerdings hatte ich ja zwischendrin mal eine Stunde Pause zum Abkühlen gemacht - ich denke also man kann davon ausgehen, dass wirklicher Dauerbetrieb nach 24 Stunden die Powerbank genau zur Hälfte geleert hätte.
Nach 27 Stunden stürzte mediamtx dann ab:
Sep 26 14:51:14 pizerow mediamtx[253]: SIGSEGV: segmentation violation
Sep 26 14:51:14 pizerow mediamtx[253]: PC=0x866a0 m=8 sigcode=1 addr=0xa8
Sep 26 14:51:14 pizerow mediamtx[253]: goroutine 0 gp=0x3ffc7e8 m=8 mp=0x3ef1808 [idle]:
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.(*unwinder).next(0x40ede74)
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/traceback.go:458 +0x1c4 fp=0x40ede48 sp=0x40eddfc pc=0x866a0
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.scanstack(0x3ffcd88, 0x3c36974)
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgcmark.go:904 +0x2bc fp=0x40edee4 sp=0x40ede48 pc=0x3c36c
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.markroot.func1()
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgcmark.go:240 +0xe8 fp=0x40edf10 sp=0x40edee4 pc=0x3a8c4
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.markroot(0x3c36974, 0x31, 0x1)
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgcmark.go:214 +0x214 fp=0x40edf6c sp=0x40edf10 pc=0x3a4ac
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.gcDrain(0x3c36974, 0xb)
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgcmark.go:1186 +0x650 fp=0x40edfbc sp=0x40edf6c pc=0x3d128
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.gcDrainMarkWorkerFractional(...)
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgcmark.go:1116
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.gcBgMarkWorker.func2()
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgc.go:1517 +0x8c fp=0x40edfe8 sp=0x40edfbc pc=0x37b48
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.systemstack(0xef1808)
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/asm_arm.s:317 +0x60 fp=0x40edfec sp=0x40edfe8 pc=0xa01b0
Sep 26 14:51:14 pizerow mediamtx[253]: goroutine 28 gp=0x3e558c8 m=8 mp=0x3ef1808 [GC worker (active)]:
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.systemstack_switch()
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/asm_arm.s:274 +0x4 fp=0x3c3ff88 sp=0x3c3ff84 pc=0xa0144
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.gcBgMarkWorker(0x3db1e40)
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgc.go:1483 +0x1f4 fp=0x3c3ffe4 sp=0x3c3ff88 pc=0x3770c
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.gcBgMarkStartWorkers.gowrap1()
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/mgc.go:1339 +0x28 fp=0x3c3ffec sp=0x3c3ffe4 pc=0x374ec
Sep 26 14:51:14 pizerow mediamtx[253]: runtime.goexit({})
Sep 26 14:51:14 pizerow mediamtx[253]: /usr/local/go/src/runtime/asm_arm.s:884 +0x4 fp=0x3c3ffec sp=0x3c3ffec pc=0xa1d14
Ich denke aber, dass das nicht allzu schlimm ist: Damit hat die Lösung länger als einen Tag durchgehalten und man könnte ja durchaus einen Watchdog instasllieren, der den Prozess oder Service in solchen Fällen von Neuem startet.
Abschließend kann ich das Fazit ziehen, dass ich sehr zufrieden mit dieser Lösung war und auch mit der Tatsache, dass eine 25000mAh Powerbank die Lösung 48 Stunden lang mit Strom versorgen kann. Das macht rund 500mA Verbrauch. Da könnte man sich durchaus noch sparsamere Varianten vorstellen - für meine Zwecke reicht es aber erst einmal allemal - letztlich war das ein Experiment mit dem Pi Zero. Die Software-Konfiguration kann man auch mit einem "echten" Raspi betreiben und diesen dann zum Bespiel mit einem 10€-PoE-Splitter problemlos über das Ethernet-Kabel mit Strom versorgen!
Synchronisierung von Aizawa-Systemen
15.11.2020
Nachdem ich hier bereits die Synchronisierung chaotischer Systeme an den üblichen Verdächtigen Lorenz und Roessler untersucht habe, habe ich mir ein weiteres vorgenommen
WeiterlesenAndroid Basteln C und C++ Chaos Datenbanken Docker dWb+ ESP Wifi Garten Geo Go GUI Gui Hardware Java Java. Komponenten Jupyter JupyterBinder Komponenten Links Linux Markdown Markup Music Numerik OpenSource PKI-X.509-CA Präsentationen Python QBrowser Rants Raspi Revisited Security Software-Test sQLshell TeleGrafana Verschiedenes Video Virtualisierung Windows Upcoming...
Englische Version des Vortrag zu Konzepten hinter digitalen Identitäten - gehalten auf der CybSecMed 2024
WeiterlesenIch habe längere Zeit keine Erweiterung meines Docker-Zoos vorgenommen - auch weil ich mir einige konzeptionelle Gedanken dazu gemacht habe. Aber ich habe auch Ideen gesammelt, was in meinem @homelab noch fehlt und was dringend ergänzt werden sollte.
WeiterlesenEine Diskussion brachte mich neulich auf eine Idee - und im Urlaub hatte ich an einem regnerischen Tag genug Zeit, die entsprechenden Experimente zu machen...
WeiterlesenManche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.
Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.
Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...
PS: Meine öffentlichen Codeberg-Repositories findet man hier.