ESP32-CAM Stream per Python3 aufzeichnen

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.

Ausgabe der ESP32-CAM in der Arduino IDE
Ausgabe der ESP32-CAM in der Arduino IDE
Eintrag der ESP32-CAM in der FritzBox
Eintrag der ESP32-CAM in der FritzBox

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()
Video von OpenCV einer ESP32-CAM
Video von OpenCV einer ESP32-CAM

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()

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert