Kürzlich erschien täglich eine Aufgabe, mit einem Paar Überwachungskameras, die an IPEYE angeschlossen sind, einen Zeitraffer zu bilden. Wenn Sie daran interessiert sind, wie eine Person mit minimalen Python-Kenntnissen damit umgegangen ist, oder wenn Sie mich auf meine Fehler hinweisen möchten, heißen wir Sie herzlich willkommen ...
Intro
Mein Vater beschloss, in einer anderen Region umzuziehen und ein Haus zu bauen. Er bat mich, bei der Videoüberwachung zu helfen. Eingabedaten:
- Es gibt keinen technischen Raum.
- Ausrüstung kann gestohlen werden.
- Benötigen Sie ein Qualitätsbild.
- Die Kameras müssen im Freien sein.
- Sie benötigen lediglich 2 Kameras.
- Ich möchte wirklich PTZ-Kameras mit Zoom.
- Ich hätte gerne eine mobile Anwendung.
Nachdem man sich die Preise in den Läden für Markenartikel angesehen hatte, entschied man sich, Noname-PoE-Kameras mit all den Brötchen auf Ali zu kaufen. Die Kameras waren billig genug - ungefähr fünftausend pro Stück.
Da ich den DVR nicht auf einer Baustelle platzieren wollte, entschied ich mich für eine Cloud-Lösung. Nachdem die Kameras angekommen waren, versuchte ich mich mit verschiedenen Diensten anzufreunden, damit alles funktionierte, einschließlich PTZ. Von all den Diensten, die ich ausprobiert habe, stellte sich heraus, dass ich mich nur mit IPEYE mit chinesischen Kameras anfreundete.
Dies beendet das Intro. Ich denke, dass jetzt allen klar sein wird, warum das Gespräch über diesen Dienst geführt wird.
Erfahrung mit IPEYE
Service als Dienstleistung. Alles was versprochen wird ist erfüllt. Der technische Support beantwortet Fragen. Der entscheidende Punkt ist, dass Sie einen Link zum RSTP-Stream angeben, die PTZ-Einstellungen ändern und alles funktioniert. Die mobile Android-Anwendung funktioniert. Es ist möglich, Gastbenutzer für ihre Kameras zu erstellen und jedem Angehörigen Zugriffsrechte zu erteilen. Das Webinterface in Vivaldi ist manchmal fehlerhaft, in Chrome sind solche Störungen weniger verbreitet. Ein bisschen langweilig beim Stöbern im Archiv.
Das Archiv von der Kamera kann heruntergeladen werden, jedoch bis zu 3 Stunden. Das Verfahren ist ziemlich zeitaufwendig.
Alles scheint in Ordnung zu sein, aber Sie spüren mit Ihrer Seele, dass etwas nicht stimmt. Und es gibt nicht genug Archivtiefe. Sie können die Tiefe erhöhen, aber die teuerste Option - 12 Monate kosten 25 Tausend Rubel pro Jahr für eine Kamera (bei Erfassung durch Erkennung).
Lassen Sie uns etwas einfallen lassen?
Das ist die Frage, die mein Vater mir gestellt hat. Mein Vater wollte alle Bauabschnitte festhalten.
Welche Möglichkeiten gibt es, um dieses Problem zu lösen? Sie können täglich zum Webinterface gehen und mehrere Videoaufnahmen von jeder Kamera exportieren. Wer wird so eine triste Aufgabe erledigen? Niemand! Mehrmals täglich Broadcast-Kameras öffnen und Screenshots machen? Na ja, auch Wahnsinn. Archivtiefe auf 1 Jahr erhöhen? Nun, eine sehr billige Lösung. Google hat mir mitgeteilt, dass die TimeLapse-Funktion in diesem Dienst bereits integriert ist, die Auflösung jedoch niedrig ist und Sie sie nicht für das zukünftige Archiv herunterladen können :(
UPD: Original-Zeitraffer kann heruntergeladen werden. Öffnen Sie dazu das Zeitraffer in der Weboberfläche. Überprüfen Sie die Webseite mithilfe von Entwicklertools und suchen Sie einen Link zu unserer Datei. Link Format:
sr <Servernummer> .ipeye.ru / api / v1 / stream / <uuid> / nvr / timelapse / 0 / <unixtimestamp> /100/video.mjpeg
Es wurde beschlossen, etwas zu schreiben, um Screenshots von der Kamera zu speichern und das endgültige Video zu erstellen.
Haftungsausschluss
Der Autor dieses Werkes ist kein Programmierer und versucht nicht, einer zu werden. OOP kennt die Grundlagen oberflächlich. Agile usw. nicht studiert. Vor einem Monat hat er sich einen kurzen Videokurs über Python angesehen und beschlossen, ihn zur Lösung des aktuellen Problems zu verwenden.
API
Es war sehr angenehm festzustellen, dass der IPEYE-Dienst eine öffentlich verfügbare
API ist . Die API enthält nur Beispiele für PHP, hat sich jedoch als nützlich erwiesen.
Basierend auf der Tatsache, dass mein Computer niemals herunterfährt, wurde das folgende Konzept entwickelt:
- Windows Scheduler führt alle 30 Minuten ein Skript aus.
- Das Skript über die API bestimmt die UUID meiner Kameras.
- Das Skript über die API empfängt das Foto von den Kameras und speichert es in einem Verzeichnis.
- Das Skript generiert einmal täglich eine Videodatei für jede Kamera.
- Der Katalog mit Quellfotos und endgültigen Videos wird an die Cloud gebunden und freigegeben.
- Verwandte, wenn sie Zeitraffer ansehen und Dateien nach Belieben bearbeiten möchten.
Um mit der API zu arbeiten, habe ich einige Funktionen geschrieben: Protokollieren und Ausführen von Anforderungen an den API-Server.
writeLog ()def writeLog(logdata): if LogEnable == 1: log_time = datetime.now() log_time = log_time.isoformat(timespec='seconds') log_file = open(log_file_path, "a+") log_file.write(log_time + ": " + str(logdata) + "\n") log_file.close else: return True
getApiResponse () def getApiResponse(method, api_uri): if method == "GET": try: r = requests.get(api_url + api_uri, timeout = api_timeout) r.raise_for_status()
Laut API haben wir die Möglichkeit, auf / devices / all zuzugreifen und Informationen zu allen Threads zu erhalten. Ich war sofort verwirrt, dass eine Autorisierung nicht erforderlich ist, wenn Sie der API-Dokumentation glauben ... Als ich nach / devices / all fragte, erhielt ich eine Fehlermeldung:
Schwerwiegender Fehler: 401 Client-Fehler: Nicht autorisiert für URL: api.ipeye.ru : 8111 / devices / all
Ich habe meine getApiResponse-Funktion so geändert, dass sie meine Anmeldeinformationen übergibt, aber ich habe auch eine 401-Fehlermeldung erhalten. Ich liste die Funktion nicht auf, weil es war in der Zukunft nicht nützlich.
Ich musste den technischen Support kontaktieren. Das Support-Team erklärte, dass Sie, um die API mit Autorisierung zu verwenden, zunächst eine Vereinbarung mit IPEYE abschließen und Ihren Webserver konfigurieren müssen. Welche Art von Webserver und warum haben sie mir nicht erklärt, aber gleichzeitig gaben sie einen Hinweis, wo man UUID-Kameras bekommt und ohne Autorisierung auf die API zugreift.
Korrespondenz mit dem SupportIch: Guten Tag. Ist es möglich, die API zu verwenden? Ich habe keine UUID-Kameras im Webinterface gefunden. Ich wollte eine Liste meiner Kameras erhalten, als ich nach api.ipeye.ru fragte: 8111 / devices / all, aber mein Benutzername / Passwort-Link funktionierte nicht.
IPEYE: Als Login / Passwort werden die Berechtigungsdaten des API-Nutzers verwendet, auf die wir vertraglich zugreifen.
Dementsprechend wird die Liste der Kameras nicht für Ihr Login angezeigt, sondern für alle Kameras der Benutzer-API.
Ich: Wie viel kostet es, auf die API von zwei Kameras zuzugreifen?
IPEYE: Dort ist alles komplizierter. Sie müssen Ihre Site starten und unsere API verwenden, um Kameras hinzuzufügen und weiter mit ihnen zu arbeiten.
Lohnt es sich, für 2 Kameras zu tun?
Ich: Im Allgemeinen benötige ich zum Verständnis nur Zugriff auf die API, um automatisch Screenshots von Kameras herunterzuladen. Zur weiteren Bildung von Zeitraffer.
IPEYE: Und was passt in diesem Fall nicht zu api.ipeye.ru/doc#AppDeviceJPEGOnline ?
Ich: Und wo finde ich die UUIDs meiner Kameras?
IPEYE: Zum Beispiel aus der Adressleiste des Browsers. Die gleiche UUID wird im "Code für die Site" als Devcode-Parameter angezeigt.
Was haben wir in dem trockenen Rückstand? Tatsächlich finden Sie uuid-Kameras in Ihrem Konto, wenn Sie sich die GET-Parameter ansehen. Es gibt eine Methode / device / jpeg / online /: uuid /: name zum Aufnehmen eines Screenshots, es gibt eine uuid und wir kannten bereits den Namen der Kamera.
Ich erstelle eine Funktion zum Speichern von Bildern aus einem Stream.
saveJpegFromStream () def saveJpegFromStream(uuid, name):
Ich mache eine Anfrage und verstehe, dass etwas nicht stimmt ... Wir haben die Akte erhalten. Das Bild stammt von meiner Kamera, ist aber verdächtig klein - 66 KB. Ich schaue mir die Eigenschaften an und verstehe, dass 608 * 342 keineswegs 1920 * 1080 ist. Wenn ich / device / thumb / online / uuid / 1920 / name anfordere, erhalte ich die Datei 1920 * 1080, aber dies ist nur die vorherige Datei 608 * 342, die auf den erforderlichen Maßstab gedehnt ist. Natürlich passte dieser Zustand nicht zu mir.
Auch während der Experimente wird festgestellt, dass der Name-Parameter nicht überprüft oder in irgendeiner Weise verwendet wird. Sie können senden, was Sie wollen.
Danach kam ich zu dem Schluss, dass der nützlichste Befehl / device / url / rtsp / darin besteht, eine Verbindung zum RTSP-Stream herzustellen. Ich musste mich an Google wenden, weil Es gab kein Verständnis für die Arbeit mit RTSP.
getStreamRTSP () def getStreamRTSP(uuid, name): api_uri = "/device/url/rtsp/" + uuid writeLog("Trying get stream RTSP link for " + name + " " + uuid) response = json.loads(getApiResponse("GET", api_uri).text) writeLog("Stream RTSP link for " + name + ": " + str(response["message"])) return str(response["message"])
saveJpegFromRTSP def saveJpegFromRTSP(name, rtspLink): writeLog("Trying save RTSP screenshot for camera: " + name) rtspClient = cv2.VideoCapture(rtspLink) if rtspClient.isOpened(): _,frame = rtspClient.read() rtspClient.release()
Nachdem ich oben einige Funktionen geschrieben hatte, wurde mir klar, dass die API für die ursprüngliche Aufgabe überhaupt nicht benötigt wurde :) Ich habe eine direkte Verbindung zum RTSP-Stream der Kamera und mit der letzten Funktion kann ich das Bild von der Kamera erfassen. Aber ich habe in diesem Schritt nicht begonnen, das Konzept zu ändern.
Bei der Arbeit mit der API gibt es zwei Vorteile: Der IPEYE-Server initialisiert den Stream viel schneller als die Kamera, und der Stream der RTSP-Kamera kann durch eine Firewall geschlossen werden.
jpg2mp4
Der letzte Schritt ist das Hinzufügen aller Bilder einer Kamera zum Video. Ich habe mich für den mp4v Codec entschieden, weil Mit MEGA können Sie diese Videodateien in einer Weboberfläche abspielen.
makeVideoFile () def makeVideoFile(name): height = 1080 width = 1920
Als Referenz: 45 JPG-Dateien mit einem Gesamtvolumen von 37,3 MB im Videoformat belegen 16,9 MB.
Vielen Dank für das Lesen meines ersten öffentlichen Artikels. Ich habe versucht, alles im Format der Geschichte zu beschreiben, und es war nicht einfach, es zu tun, weil ich auf dem Weg nach draußen keinen trockenen Artikel haben wollte.
Ich freue mich über Kommentare, da ich Python vor weniger als einem Monat getroffen habe.
Das vollständige Skript mit erweiterten Kommentaren finden Sie auf
Github . Außerdem berücksichtigt das Skript den Unterschied in den Zeitzonen und alle verbleibenden Funktionen werden so geschrieben, dass sie schnell auf eine andere Anzahl von Kameras skaliert werden können.