Skip to Content

Video mit ESP32-WROVER CAM streamen

Video mit ESP32-WROVER CAM streamen

In diesem Tutorial zeige ich dir, wie du Video von einem Freenove ESP32-WROVER CAM Board über dein lokales Wi-Fi-Netzwerk in deinem Webbrowser streamen kannst. So kannst du ganz einfach dein eigenes kabelloses Überwachungskamerasystem bauen, das du von deinem Computer aus überwachen kannst.

Falls du dieses Board noch nicht benutzt hast, empfehle ich dir, zuerst das Programming the ESP32-WROVER CAM Tutorial zu lesen, das dir den Einstieg mit dem Board erleichtert.

Benötigte Teile

Für dieses Tutorial benötigst du ein Freenove ESP32-WROVER CAM Board. Üblicherweise wird das Board mit Extras wie einer SD-Karte, einem SD-Kartenleser und einem USB-C-Kabel geliefert. Falls diese fehlen, habe ich sie unten ebenfalls verlinkt.

ESP32-WROVER CAM

USB-C-Kabel

SD-Kartenleser

MicroSD-Karte 16GB

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Video-Streaming

In diesem Projekt implementieren wir einen Video-Streaming-Server, der auf dem ESP32-WROVER läuft. Die Kamera des ESP32-WROVER nimmt Bilder auf und stellt sie über Wi-Fi bereit. Der Wi-Fi-Router überträgt diese Bilder an den Webbrowser auf deinem PC, der die Bilder als Videostream anzeigt. Das folgende Bild zeigt die Architektur des Systems:

Streaming Video via local Wi-Fi
Video-Streaming über lokales Wi-Fi

Beachte, dass der Videostream nicht verschlüsselt oder gesichert ist, sondern nur unter einer URL innerhalb deines lokalen Wi-Fi-Netzwerks sichtbar ist, z.B. 192.168.2.40/stream. Nur jemand mit Zugang zu deinem Wi-Fi-Netzwerk kann den Videostream sehen.

Einfacher Code für einen Video-Streaming-Server

Der ESP32-WROVER CAM Core enthält Beispielcode für einen CameraWebServer, der Videos streamt; siehe das Programming the ESP32-WROVER CAM Tutorial für Details. Dieser Code ist jedoch komplex und die Benutzeroberfläche des Webservers bietet viele Optionen.

Das ist super zum Ausprobieren, aber wenn du nur den reinen Videostream möchtest (z.B. für Home Assistant) und einfachen Code, den du mit anderen Funktionen wie einem bewegungsaktivierten Videostream kombinieren kannst, ist der folgende Code leichter zu verwenden.

Die Vereinfachung ist hauptsächlich der esp32cam Bibliothek zu verdanken, die du über den Library Manager in der Arduino IDE installieren kannst. Suche einfach nach „esp32cam“ und klicke auf INSTALLIEREN. Das Bild unten zeigt die abgeschlossene Installation:

esp32cam library installed via Library Manager
esp32cam-Bibliothek installiert über Library Manager

Unten findest du den kompletten Code für den Video-Streaming-Server, der die esp32camBibliothek verwendet. Schau ihn dir kurz an, dann gehen wir auf die Details ein:

#include "WebServer.h"
#include "WiFi.h"
#include "esp32cam.h"

const char* WIFI_SSID = "SSID";
const char* WIFI_PASS = "PASSWORD";
const char* URL = "/stream";
const auto RESOLUTION = esp32cam::Resolution::find(800, 600);

WebServer server(80);

void handleStream() {
  static char head[128];
  WiFiClient client = server.client();

  server.sendContent("HTTP/1.1 200 OK\r\n"
                     "Content-Type: multipart/x-mixed-replace; "
                     "boundary=frame\r\n\r\n");

  while (client.connected()) {
    auto frame = esp32cam::capture();
    if (frame) {
      sprintf(head,
              "--frame\r\n"
              "Content-Type: image/jpeg\r\n"
              "Content-Length: %ul\r\n\r\n",
              frame->size());
      client.write(head, strlen(head));
      frame->writeTo(client);
      client.write("\r\n");
    }
  }
}

void initCamera() {
  using namespace esp32cam;
  Config cfg;
  cfg.setPins(pins::FreeNove);
  cfg.setResolution(RESOLUTION);
  cfg.setBufferCount(2);
  cfg.setJpeg(80);
  Camera.begin(cfg);
}

void initWifi() {
  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  Serial.printf("Stream at: http://%s%s\n",
                WiFi.localIP().toString().c_str(), URL);
}

void initServer() {
  server.on(URL, handleStream);
  server.begin();
}

void setup() {
  Serial.begin(115200);
  initWifi();
  initCamera();
  initServer();
}

void loop() {
  server.handleClient();
}

Bibliotheken

Das Sketch beginnt mit dem Einbinden der notwendigen Bibliotheken:

#include "WebServer.h"
#include "WiFi.h"
#include "esp32cam.h"

Diese Bibliotheken ermöglichen HTTP-Server-Funktionalität (WebServer.h), Wi-Fi-Konnektivität (WiFi.h) und Kamerasteuerung mit der esp32cam Bibliothek.

Konstanten

Als nächstes definieren wir Konstanten für Wi-Fi- und Kameraeinstellungen:

const char* WIFI_SSID = "SSID";
const char* WIFI_PASS = "PASSWORD";
const char* URL = "/stream";
const auto RESOLUTION = esp32cam::Resolution::find(800, 600);

Die WIFI_SSID und WIFI_PASSVariablen speichern die Zugangsdaten für das Wi-Fi-Netzwerk. Du musst SSID und PASSWORD durch die tatsächlichen Zugangsdaten deines Netzwerks ersetzen.

Der URL ist der Pfad, unter dem der Videostream bereitgestellt wird. Du kannst ihn nach Belieben ändern, z.B. „/video“ oder „/frontdoor“, achte nur darauf, den Schrägstrich (‚/‘) am Anfang beizubehalten.

Die RESOLUTION legt die gewünschte Auflösung der Kamera fest. Unten findest du eine Liste möglicher Kameraauflösungen, wobei je nach Kamera nicht alle funktionieren:

  • 96×96
  • 160×120
  • 128×128
  • 176×144
  • 240×176
  • 240×240
  • 320×240
  • 320×320
  • 400×296
  • 480×320
  • 640×480
  • 800×600
  • 1024×768
  • 1280×720
  • 1280×1024
  • 1600×1200

Objekte

Die folgende Zeile erstellt das HTTP-Server-Objekt, das auf Port 80 lauscht. Das ist unser Webserver, der den Videostream bereitstellt.

WebServer server(80);

handleStream

Die Funktion handleStream() verarbeitet den Videostream, sobald ein Client den /streamPfad aufruft:

void handleStream() {
  static char head[128];
  WiFiClient client = server.client();

Diese Zeile holt den aktuell mit dem Server verbundenen Client. Die Antwort wird dann vorbereitet:

server.sendContent("HTTP/1.1 200 OK\r\n"
                   "Content-Type: multipart/x-mixed-replace; "
                   "boundary=frame\r\n\r\n");

Dieser Header teilt dem Browser mit, dass er einen multipart MJPEG-Stream erhält, bei dem jeder Teil durch eine Grenze namens frame getrennt ist.

Innerhalb der Schleife erfasst die Funktion zuerst einen Frame von der Kamera:

  while (client.connected()) {
    auto frame = esp32cam::capture();

Wenn ein Frame erfolgreich aufgenommen wurde, wird ein Header erstellt, der das JPEG-Bild beschreibt, und an den Client gesendet:

    if (frame) {
      sprintf(head,
              "--frame\r\n"
              "Content-Type: image/jpeg\r\n"
              "Content-Length: %ul\r\n\r\n",
              frame>size());
      client.write(head, strlen(head));
      frame->writeTo(client);
      client.write("\r\n");
    }

initCamera

Die initCamera() Funktion konfiguriert und startet die ESP32-WROVER Kamera:

void initCamera() {
  using namespace esp32cam;
  Config cfg;
  cfg.setPins(pins::FreeNove);
  cfg.setResolution(RESOLUTION);
  cfg.setBufferCount(2);
  cfg.setJpeg(80);
  Camera.begin(cfg);
}

Zuerst wird ein Config Objekt erstellt. Die setPins Funktion konfiguriert die Kamerapins basierend auf dem FreeNove Board. Das ESP32-WROVER CAM ist von FreeNove und genau das musst du hier einstellen. Du findest die pin configurations of other supported boards here.

setResolution definiert die zu verwendende Auflösung, während setBufferCount bestimmt, wie viele Bildpuffer intern genutzt werden, was zu schnelleren Bildraten beitragen kann.

Die setJpeg Funktion setzt die JPEG-Kompressionsqualität zwischen 0 und 100. 80 ist ein guter Kompromiss zwischen Qualität und Größe. 90 liefert bessere Qualität, aber eine geringere Größenreduktion. Für schnellere Videos kannst du Auflösung und JPEG-Kompression reduzieren, allerdings erhältst du dann kleinere Bilder mit geringerer Qualität.

Schließlich initialisiert Camera.begin(cfg) die Kamera mit diesen Einstellungen.

initWifi

Die initWifi() Funktion verbindet das ESP32-WROVER Board mit dem angegebenen Wi-Fi-Netzwerk:

void initWifi() {
  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  Serial.printf("Stream at: http://%s%s\n",
                WiFi.localIP().toString().c_str(), URL);
}

WiFi.persistent(false) deaktiviert das Speichern der Zugangsdaten im Flash, was die Wiederverbindung beschleunigt. Das Gerät wird in den Station-Modus (WIFI_STA) versetzt und versucht, sich mit den angegebenen Zugangsdaten zu verbinden.

Nach der Verbindung werden die IP-Adresse und der Stream-Pfad im Serial Monitor ausgegeben. Du musst diese URL in die Adresszeile deines Browsers kopieren, um den Videostream zu sehen. Die tatsächliche URL hängt von deinem ESP32-WROVER Board ab, aber du kannst den Suffix „stream“ ändern. Bei meinem Board sehe ich folgende URL im Serial Monitor:

Streaming URL printed to Serial Monitor
Streaming-URL im Serial Monitor ausgegeben

Daher kopiere ich „http://192.168.2.40/stream“ in die Adresszeile meines Chrome-Browsers, um das Video zu sehen.

initServer

Die initServer() Funktion verknüpft den Streaming-Pfad mit dem Handler und startet den Server:

void initServer() {
  server.on(URL, handleStream);
  server.begin();
}

Dies ordnet alle Anfragen an /stream der handleStream() Funktion zu und startet dann den Server.

setup

Die setup() Funktion startet die serielle Kommunikation, verbindet mit Wi-Fi, initialisiert die Kamera und richtet den Webserver ein:

void setup() {
  Serial.begin(115200);
  initWifi();
  initCamera();
  initServer();
}

loop

Schließlich verarbeitet die loop() Funktion kontinuierlich eingehende HTTP-Anfragen:

void loop() {
  server.handleClient();
}

Diese Zeile erlaubt dem ESP32-WROVER, auf Client-Anfragen zu reagieren, indem registrierte Handler wie handleStream() aufgerufen werden.

Insgesamt erstellt dieser Code einen einfachen, aber effektiven MJPEG-Streaming-Server, der von jedem Webbrowser im gleichen Netzwerk zugänglich ist und einen Live-Kamerafeed vom ESP32-WROVER CAM liefert.

Um diesen Code auf dein ESP32-WROVER CAM zu laden, wähle das ESP32 Wrover Module Board aus und drücke den Download-Button.

Select ESP32 Wrover Module as board
Wähle ESP32 Wrover Module als Board

Falls du dabei Hilfe brauchst, schau dir unser Programming the ESP32-WROVER CAM Tutorial an.

Fazit

In diesem Tutorial hast du gelernt, wie du Video von einem ESP32-WROVER CAM über dein lokales Wi-Fi-Netzwerk in deinen Webbrowser streamst.

Das ESP32-WROVER CAM funktioniert super, ist aber ein recht großes Board. Wenn du ein Board mit kleinerem Formfaktor brauchst, empfehle ich das XIAO-ESP32-S3-Sense, das winzig ist – ein Würfel von etwa 20 mm Kantenlänge.

Für Objekterkennung schau dir auch das Object Detection with ESP32-CAM and YOLO Tutorial an. Es ist für das ESP32-CAM geschrieben, benötigt aber nur eine minimale Änderung (cfg.setPins(pins::FreeNove)), um mit dem ESP32-WROVER CAM zu funktionieren.

Wenn du Fragen hast, hinterlasse sie gerne im Kommentarbereich.

Viel Spaß beim Tüfteln ; )