In diesem Beitrag möchte ich dir zeigen, wie du ein Stream der ESP32-CAM per Python3 aufzeichnen kannst.
Die ESP32-CAM habe ich dir bereits im Beitrag Einrichten der ESP32-CAM und erster betrieb vorgestellt und gezeigt wie man den Sketch / das Program “CameraWebServer” hochlädt.
Für diesen Beitrag verwende ich das Beispiel “CameraWebServer” ohne Änderungen.
Ermitteln der Adresse der ESP32-CAM
Die Adresse der ESP32-CAM kannst du entweder aus der seriellen Schnittstelle ablesen (in der Arduino IDE) oder du schaust in deinen Router.
Die Weboberfläche der ESP32-CAM kannst du über die IP-Adresse / den Namen des Gerätes und dem default HTTP Port 80 aufrufen.
http://192.168.178.33:80
http://esp32-arduino:80
Den Port kannst du in diesem Falle weglassen, bzw. der Browser Google Chrome entfernt diesen von selbst.
Nachdem wir nun die Adresse der ESP32-CAM ermittelt haben, können wir den Stream entweder über die IP-Adresse inkl. des Seitennamens “/stream” aufrufen oder mit dem Namen des Gerätes.
http://192.168.178.33:81/stream
http://esp32-arduino:81/stream
Aufzeichnen mit OpenCV2
Auf der Seite How to Record Video in Python using OpenCV habe ich ein kleines Beispiel gefunden, welches sich mit sehr wenigen Anpassungen für die ESP32-CAM nutzen lässt.
Datei ‘requirements.txt’
opencv-python~=4.5.5.64
requests~=2.27.1
Datei ‘recordStream.py’
''' Beispiel von http://www.learningaboutelectronics.com/Articles/How-to-record-video-Python-OpenCV.php (kleinere Anpassungen durch mich) ''' import cv2 import time # IP Adresse der ESP32-CAM ipAdress = '192.168.178.33' # Streaming Adresse aufbauen streamAddress = 'http://' + ipAdress + ':81/stream' cap = cv2.VideoCapture(streamAddress) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) filename = time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".mp4" writer = cv2.VideoWriter(filename, cv2.VideoWriter_fourcc(*'DIVX'), 20, (width, height)) while True: ret, frame = cap.read() writer.write(frame) cv2.imshow('frame', frame) # ESC Taste zum Abbrechen if cv2.waitKey(1) & 0xFF == 27: break cap.release() writer.release() cv2.destroyAllWindows()
Anpassen der Auflösung
Wenn man das obige Skript startet, dann wird die Aufzeichnung mit der Standardauflösung von 320×240 Pixel aufgenommen.
Diese Auflösung kann man durch das Absenden eines Requests VOR dem Start der Aufzeichnung des Videos anpassen.
Im nachfolgenden Code wird die Auflösung auf 1024×768 Pixel geändert.
""" Index | Auflösung 13 | 1600 x 1200 12 | 1280 x 1024 11 | 1280 x 720 10 | 1024 x 768 9 | 800 x 600 8 | 640 x 480 7 | 480 x 320 6 | 400 x 296 5 | 320 x 240 4 | 240 x 240 3 | 240 x 176 2 | 176 x 144 1 | 160 x 120 0 | 96 x 96 """ import requests ipAdress = '192.168.178.33' requests.get('http://'+ipAdress+'/control?var=framesize&val=10')
Möchte man nun eine Auflösung von zbsp 640×480 Pixel (VGA) einstellen, so muss man den Index 8 absenden.
Modifikation 1 – beenden nach X Sekunden
Wenn das Skript soll sich selbständig nach einer Zeit X beenden soll, so muss man während der Laufzeit die Sekunden aufzeichnen und dieses mit einer maximalen Zeit vergleichen.
''' Beispiel von http://www.learningaboutelectronics.com/Articles/How-to-record-video-Python-OpenCV.php (kleinere Anpassungen durch mich) ''' import cv2 import time # IP Adresse der ESP32-CAM ipAdress = '192.168.178.33' # Streaming Adresse aufbauen streamAddress = 'http://' + ipAdress + ':81/stream' cap = cv2.VideoCapture(streamAddress) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) filename = time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".mp4" writer = cv2.VideoWriter(filename, cv2.VideoWriter_fourcc(*'DIVX'), 20, (width, height)) # Zeit wann das Skript gestartet wurde in Sekunden start_time = int(time.time()) # Maximale Aufnahmezeit in Sekunden time_max = 10 # vergangene Sekunden time_elapsed = 0 while True: ret, frame = cap.read() writer.write(frame) cv2.imshow('frame', frame) if cv2.waitKey(1): if time_elapsed > time_max: break if (time.time() - start_time) - time_elapsed > 0: time_elapsed = time.time() - start_time # ESC Taste zum Abbrechen if cv2.waitKey(1) & 0xFF == 27: break cap.release() writer.release() cv2.destroyAllWindows()
Modifikation 2 – beenden nach X Byte
Man kann auch das Skript nach X Byte beenden, bzw. eher nach X Kbyte. Dazu müssen wir zusätzlich das Modul “os” importieren von welchem wir die Funktion “os.path.getesize” verwenden können um die Dateigröße (in Byte) zu ermitteln.
''' Beispiel von http://www.learningaboutelectronics.com/Articles/How-to-record-video-Python-OpenCV.php (kleinere Anpassungen durch mich) ''' import cv2 import time import os # IP Adresse der ESP32-CAM ipAdress = '192.168.178.33' # Streaming Adresse aufbauen streamAddress = 'http://' + ipAdress + ':81/stream' cap = cv2.VideoCapture(streamAddress) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) filename = time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".mp4" writer = cv2.VideoWriter(filename, cv2.VideoWriter_fourcc(*'DIVX'), 20, (width, height)) # Maximale Dateigröße in Kilobyte (hier 500 Kb) max_filesize = 1024 * 500 while True: ret, frame = cap.read() writer.write(frame) cv2.imshow('frame', frame) if cv2.waitKey(1): # Auslesen der Dateigröße filesize = os.path.getsize(filename) # Wenn die Datei größer ist als das Maximum dann Abbrechen if filesize > max_filesize: break # ESC Taste zum Abbrechen if cv2.waitKey(1) & 0xFF == 27: break cap.release() writer.release() cv2.destroyAllWindows()