Problem beim Bilder einlesen mit Python/Kivy und Shellskript

Ein neuer Artikel wurde veröffentlicht
  • Hallo liebe Raspberrybastler :)


    Ich baue mir aktuell aus einem Raspberry eine Türsprechanlage mit Überwachungsfunktion und "Live" Bild einer IP-Überwachungskamera.

    Ich habe bis jetzt alles in Python mit Hilfe von Kivy (für einen Touchscreen) geschrieben und hat auch alles soweit funktioniert. Jetzt hab ich mich daran gemacht die Kamera noch mit einzubinden und da hab ich jetzt so meine Probleme.

    Ich hab mir das ganze so vorgestellt, dass der Pi über ffmpeg jede Sek einen Screenshot macht und ich dann jede Sek das aktuelle Bild neu lade. Es würde natürlich auch noch die Möglichkeit bestehen den Livestream der Kamera direkt an Kivy zu übergeben, aber das hab ich bis jetzt auch nicht zum laufen bekommen bzw. nicht mal einen groben Ansatz dafür.:conf:Deshalb auch aktuell die Sache mit "jeder Sek 1 Bild" und das funktioniert auch bis zu ca. 10 Bilder problemlos und dann gibt er mir nur noch ein Schwarzes Bild aus. Ich weiß aber nicht woran es liegen könnte, dass es Anfangs funktioniert und nach ein paar Bildern nicht mehr:conf:

    Das ffmpeg immer im Hintergrund laufen kann hab ich ein Shellskript geschrieben:

    Shell-Script
    1. #!/bin/bash
    2. /usr/bin/ffmpeg -i "rtsp://***" -vf fps=1 /home/***/Pictures/Cam/live/cam%02d.jpg

    und dieses Starte ich beim Initialisieren des Bildschrims und das funktioniert auch passend, also erstellt mir jede Sek brav ein Bild.


    Cam_Update wird jede Sek aufgerufen.

    und self.Bild übergibt dann das aktuelle Bild an die .kv Datei für Kivy.


    Ich verstehe nicht wieso er Anfangs keine Probleme hat die Bilder einzulesen, aber sobald das ca. 11 Bild kommt, er dann nur noch ein "schwarzes" Bild ausgibt, aber ganz selten, vll so alle 40 Bilder, gibt er wieder 1 oder 2 Bilder richtig aus.:conf:

    (Die Bilder sind aber alle ganz normal, wenn ich es mir per ftp hole.


    Ist es möglich die beiden Skripte (sh und py) zu synchronisieren? Also das er zu 100% fertig ist das Bild zu machen und es erst dann einliest? Könnte mir vll vorstellen das es daran liegt, aber ich glaub fast nicht.


    Vll weiß jemand von euch Rat :helpnew::daumendreh2:

  • Hallo,


    meine 1. Vermutung wäre auch, dass der Takt von jede Sekunden 1 Bild zu viel ist.


    Was auch sein könnte ist, dass dein Python-Skript auf eine angelegte, aber noch nicht fertig gefüllte / konvertierte JPEG-Datei zugreifen will. Abhilfe: nicht auf das neuste Bild, sondern das 2. neuste zugreifen. Nachteil: du bist 1 Sekunde "hinterher".


    Du könntest ggf. auch den Aufruf von ffmpeg per `subprocess` direkt in Python machen. Dann würden den Skript so lange blockieren, bis die Konvertierung abgeschlossen ist.


    Zum Skript:


    • Warum ist `counter_bilder` global? Vergiß' am besten, dass es `global` gibt. In 99,9% der Fälle braucht man das nicht.
    • Der Zähler ist so wie so überflüssig. len(Ordnerliste) liefert dir im gezeigten Code die Anzahl der Dateien.
    • Das `str()` in Zeile 10+12 sollte überflüssige sein.
    • Pfade setzt man unter Python mit `os.path.join()` zusammen, nicht per +
    • Nackte `try... except` möchtest du nicht verwenden, weil du damit _alle_ Fehler abfängst. Was man normalerweise nicht will, weil ggf. auch Fehler verdeckt werden, die man sehen will. Man fängt üblicherweise gezielt bestimmt Fehler ab.
    • Warum übergibst du `dt` der Funktion, nutzt es aber nicht im gezeigten Code?
    • Deine Funktion `Cam_Update` ist in sofern schlecht, als dass eine Funktion genau _eine_ Aufgabe erfüllen soll. Bei dir sind es aber zwei: `self.Bild` zuweisen und aufräumen. Zwei Aufgaben -> zwei Funktionen.

    Gruß, noisefloor

  • Schon mal vielen Dank für die Hilfe.


    Ich hab bereits versucht auf das vorletzte Bild zuzugreifen mit "Name = str(Ordnerliste[-2])" statt "Name = str(Ordnerliste[-1])" und dies hat leider keinen Effekt auf das Problem gehabt. Deswegen bin ich mir inzwischen ziemlich sicher, dass es nicht an einem unfertigen JPEG-Datei liegt.

    Außerdem ergibt das leider auch Probleme, da der Stream auch schon 1 Sek "hinterher" ist, deswegen würde ich insgesamt dann schon mindestens 3 Sek hinterher sein. Umso weniger Zeit, um so besser für den Sinn :conf:


    "Subprocess" hab ich mir auch schon überlegt, stell mir aber als Problem dabei vor, dass ffmpeg zum starten schon ein paar sek braucht, es würde dann vermutlich bei jedem Bild ein paar Sek dauern bis es ein Bild gemacht wird. Dies ist dann auch nicht der Sinn der Sache. Außerdem möchte ich ungern das Skript blockieren, da es auch für die Klingel etc. verantwortlich ist und diese dann fast immer blockiert wäre. (Musste wegen Kivy eine einzelne Datei sein, soweit ich weiß)


    Die andere Punkte die du genannt hast, werde ich mal in einer freien Minute bearbeiten:danke_ATDE:


    Ich werde jetzt auch mal versuchen direkt per ffmpeg ein Video aufzunehmen, dass Kivy dann direkt ausgibt. Muss aber schauen, ob es mit der unfertigen MP4-Datei klar kommt und ob die Datei im Dauerbetrieb nicht zu groß wird. Aber besser wäre whrl schon die Version mit jede Sek ein Bild:denker:


    Viele Grüße



    Ergänzung:

    Ach und den Try-Except Block hab ich genau wegen dem Starten von ffmpeg gemacht, da das SH-Skript ein paar Sek braucht bis es das erste Bild aufnimmt.

  • Hallo Leute,

    Schon mal vielen, vielen Dank für alle die mir bereits versucht haben zu helfen :thumbup::thumbup::danke_ATDE:


    Also ich habs jetzt meinen Code ein bisschen verbessert und hab glaub ich auch das Problem mit dem Bild fast gelöst. Aber leider nur fast und ich glaube es liegt jetzt an Kivy, aber ich komm nicht drauf woran genau :wallbash:

    Also mein Code macht jetzt mit cam.sh jede sek ein Bild:

    Shell-Script
    1. #!/bin/bash
    2. /usr/bin/ffmpeg -y -i 'rtsp://****/11' -vf fps=1 -update 1 -f image2 livecam.jpg

    und überschreibt die ganze Zeit livecam.jpg. Dies funktioniert auch soweit bis auf das er mir "livecam.jpg?" erzeugt (liegt aber glaub ich an ffmpeg oder den rtsp-Stream).

    Dies konvertier ich dann noch mit

    Code
    1. os.popen("cp livecam.jpg? livecam_conv.jpg")

    und diese livecam_conv.jpg lässt sich problemlos öffnen:thumbup:

    Leider aktualisiert mir Kivy aber das Bild nicht, obwohl die "livecam_conv.jpg" immer aktualisiert wird :denker:

    vll hat jemand von euch noch eine Ahnung wieso nicht :danke_ATDE:

    Hier noch ein Teil meiner .kv Datei:

    und mein dazugehöriger Python-Code:

    P.S.: Das z.B. bei Cam_Update self und time übergeben werden liegt an Kivy, da es automatisch die Zeit beim Aufruf mit übergibt.


    Ich versteh nicht warum er z.B. self.Datum oder self.Uhrzeit richtig aktualisiert aber self.Bild nicht :conf:


    Ach und ich überblicke Kivy und Python noch nicht mal ansatzweise komplett, also habt für meinen vll schlechten Programmierstil Verständnis ^^