Neste tutorial, vou mostrar como transmitir vídeo de uma placa Freenove ESP32-WROVER CAM pela sua rede Wi-Fi local para o seu navegador Web. Isto significa que pode facilmente construir o seu próprio sistema de câmaras de vigilância sem fios que pode monitorizar a partir do seu computador.
Se nunca usou esta placa antes, sugiro que leia o Programming the ESP32-WROVER CAM tutorial primeiro, que o ajuda a começar com a placa.
Peças Necessárias
Vai precisar de uma placa Freenove ESP32-WROVER CAM para seguir este tutorial. Normalmente a placa vem com extras como um cartão SD, um leitor de cartão SD e um cabo USB-C, mas caso faltem, também os liguei abaixo.

ESP32-WROVER CAM

Cabo USB C

Leitor de Cartão SD

Cartão MicroSD 16GB

Arduino IDE
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.
Transmissão de Vídeo
Neste projeto vamos implementar um servidor de streaming de vídeo que corre no ESP32-WROVER. A câmara do ESP32-WROVER tira imagens e serve-as via Wi-Fi. O router Wi-Fi transporta estas imagens para o navegador Web no seu PC, que as exibe como um fluxo de vídeo. A imagem abaixo ilustra a arquitetura do sistema:

Note que o fluxo de vídeo não é encriptado nem seguro, mas será visível apenas numa URL dentro da sua rede Wi-Fi local, por exemplo 192.168.2.40/stream. Só quem tiver acesso à sua rede Wi-Fi poderá ver o fluxo de vídeo.
Código Simples para um Servidor de Streaming de Vídeo
O core para o ESP32-WROVER CAM vem com código de exemplo para um CameraWebServer que transmite vídeos; veja o Programming the ESP32-WROVER CAM tutorial para detalhes. Mas esse código é complexo e a interface do servidor Web tem muitas opções.
Isto é ótimo para experimentar, mas se quiser apenas o fluxo de vídeo simples (por exemplo, para Home Assistant) e código simples que possa integrar com outras funções, como um streaming ativado por movimento, então o código seguinte é mais fácil de usar.
A simplificação deve-se em grande parte à biblioteca esp32cam, que pode instalar via Library Manager no Arduino IDE. Basta procurar por “esp32cam” e pressionar INSTALL. A imagem abaixo mostra a instalação concluída:

Abaixo encontra o código completo para o servidor de streaming de vídeo, que usa a biblioteca esp32cam. Dê uma vista rápida e depois analisamos os detalhes:
#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();
}
Bibliotecas
O sketch começa por incluir as bibliotecas necessárias:
#include "WebServer.h" #include "WiFi.h" #include "esp32cam.h"
Estas bibliotecas permitem a funcionalidade de servidor HTTP (WebServer.h), conectividade Wi-Fi (WiFi.h) e controlo da câmara usando a biblioteca esp32cam.
Constantes
De seguida, definimos constantes para as configurações de Wi-Fi e da câmara:
const char* WIFI_SSID = "SSID"; const char* WIFI_PASS = "PASSWORD"; const char* URL = "/stream"; const auto RESOLUTION = esp32cam::Resolution::find(800, 600);
As variáveis WIFI_SSID e WIFI_PASS guardam as credenciais da rede Wi-Fi. Terá de substituir SSID e PASSWORD pelos dados reais da sua rede Wi-Fi.
O URL é o caminho onde o fluxo de vídeo será servido. Pode alterá-lo para o que quiser. Por exemplo, “/video” ou “/frontdoor”, só certifique-se de manter a barra (‘/’) no início.
O RESOLUTION define a resolução desejada para a câmara. Abaixo está uma lista dos valores possíveis para a resolução da câmara, embora dependendo da câmara nem todos possam funcionar:
- 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
Objetos
A linha seguinte cria o objeto do servidor HTTP que escuta na porta 80. Esse é o nosso servidor web que fornece o fluxo de vídeo.
WebServer server(80);
handleStream
A função handleStream() trata o fluxo de vídeo sempre que um cliente acede ao caminho /stream:
void handleStream() {
static char head[128];
WiFiClient client = server.client();
Esta linha obtém o cliente atual ligado ao servidor. A resposta é então preparada:
server.sendContent("HTTP/1.1 200 OK\r\n"
"Content-Type: multipart/x-mixed-replace; "
"boundary=frame\r\n\r\n");
Este cabeçalho informa o navegador que vai receber um fluxo MJPEG multipartido, onde cada parte é separada por um limite chamado frame.
Dentro do loop, a função primeiro captura um frame da câmara:
while (client.connected()) {
auto frame = esp32cam::capture();
Se um frame for capturado com sucesso, é construído um cabeçalho a descrever a imagem JPEG, e enviado ao cliente:
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
A função initCamera() configura e inicia a câmara ESP32-WROVER:
void initCamera() {
using namespace esp32cam;
Config cfg;
cfg.setPins(pins::FreeNove);
cfg.setResolution(RESOLUTION);
cfg.setBufferCount(2);
cfg.setJpeg(80);
Camera.begin(cfg);
}
Primeiro, é criado um objeto Config. A função setPins configura os pinos da câmara com base na placa FreeNove. A ESP32-WROVER CAM é da FreeNove e é isso que precisa definir aqui. Pode encontrar o pin configurations of other supported boards here.
setResolution define a resolução a usar, enquanto setBufferCount determina quantos buffers de imagem são usados internamente, o que pode ajudar a obter taxas de frames mais rápidas.
A função setJpeg define a qualidade da compressão JPEG entre 0 e 100. 80 é um bom equilíbrio entre qualidade e tamanho. 90 dá melhor qualidade mas uma redução menor no tamanho da imagem. Para vídeo mais rápido pode reduzir a resolução e a compressão JPEG, mas obviamente terá imagens menores com qualidade inferior.
Finalmente, Camera.begin(cfg) inicializa a câmara com estas configurações.
initWifi
A função initWifi() liga a placa ESP32-WROVER à rede Wi-Fi especificada:
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) desativa a escrita das credenciais na flash, o que acelera a reconexão. O dispositivo é configurado para o modo station mode (WIFI_STA), e tenta ligar-se ao Wi-Fi usando as credenciais fornecidas.
Uma vez ligado, o endereço IP e o caminho do fluxo são impressos no monitor serial. Terá de copiar e colar esta URL impressa na barra de endereços do seu navegador para ver o fluxo de vídeo. A URL real dependerá da sua placa ESP32-WROVER, mas pode alterar o sufixo “stream”. Na minha placa, vejo a seguinte URL no Monitor Serial:

Portanto, copio “http://192.168.2.40/stream” para a barra de endereços do meu navegador Chrome para aceder ao vídeo.
initServer
A função initServer() liga o caminho de streaming ao handler e inicia o servidor:
void initServer() {
server.on(URL, handleStream);
server.begin();
}
Isto mapeia qualquer pedido a /stream para a função handleStream(), e depois inicia o servidor.
setup
A função setup() inicia a comunicação serial, liga ao Wi-Fi, inicializa a câmara e configura o servidor web:
void setup() {
Serial.begin(115200);
initWifi();
initCamera();
initServer();
}
loop
Finalmente, a função loop() trata continuamente os pedidos HTTP recebidos:
void loop() {
server.handleClient();
}
Esta linha permite que o ESP32-WROVER responda a pedidos dos clientes invocando quaisquer handlers registados, como handleStream().
No total, este código cria um servidor de streaming MJPEG simples mas eficaz que pode ser acedido a partir de qualquer navegador web dentro da mesma rede, fornecendo um feed de câmara ao vivo do ESP32-WROVER CAM.
Para transferir esse código para o seu ESP32-WROVER CAM, selecione a placa ESP32 Wrover Module e pressione o botão de download.

Se precisar de ajuda com isto, dê uma vista de olhos ao nosso Programming the ESP32-WROVER CAM tutorial.
Conclusões
Neste tutorial aprendeu como transmitir vídeo de um ESP32-WROVER CAM pela sua rede Wi-Fi local para o seu navegador Web.
O ESP32-WROVER CAM funciona muito bem, mas é uma placa relativamente grande. Se precisar de uma placa com menor dimensão, sugiro o XIAO-ESP32-S3-Sense, que é minúsculo – um cubo de cerca de 20mm.
Também para deteção de objetos, dê uma vista de olhos ao tutorial Object Detection with ESP32-CAM and YOLO. Está escrito para o ESP32-CAM mas requer apenas uma alteração mínima (cfg.setPins(pins::FreeNove)) para funcionar com o ESP32-WROVER CAM.
Se tiver alguma dúvida, sinta-se à vontade para deixar nos comentários.
Boas experiências a criar ; )

