ESP32-S3-WROOM-V1 doesn't stream video on browser

Hi guys, I'm trying to stream video using the IP address but what I get when I access the browser (Google Chrome) is a white screen.
I have been using the board for capturing pictures (using the same code below but different function for streaming: void startCameraServer_stream()) and it works just fine.

Setting:
USB CDC On Boot ---> Enabled
Flash Size ---> 8MB(64Mb)
Partition Scheme ---> 8M with spiffs (3MB APP/1.5MB SPIFFS)
PSRAM ---> OPI PSRAM

Could you help me to figure out what I'm missing? (Below the code)

#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include "esp_camera.h"
#include "esp_system.h"
#include <WiFi.h>

const char *ssid = "*****"; //wifi name
const char *password = "*****";//wifi password
AsyncWebServer server(80); 

#define CAMERA_MODEL_ESP32S3_EYE //it is designed for facial recognition and AI applications.

#if defined(CAMERA_MODEL_ESP32S3_EYE)
#define PWDN_GPIO_NUM  -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM  15
#define SIOD_GPIO_NUM  4
#define SIOC_GPIO_NUM  5
#define Y2_GPIO_NUM 11
#define Y3_GPIO_NUM 9
#define Y4_GPIO_NUM 8
#define Y5_GPIO_NUM 10
#define Y6_GPIO_NUM 12
#define Y7_GPIO_NUM 18
#define Y8_GPIO_NUM 17
#define Y9_GPIO_NUM 16
#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM  7
#define PCLK_GPIO_NUM  13

#else
#error "Camera model not selected"
#endif

void startCameraServer_stream(); // Video only
void camera_settings();
int camera_cfg();
void wifi();

void setup() {
  Serial.begin(115200);
 
  if(camera_cfg()) { //Setting PINs configuration for camera
    wifi();
    camera_settings();
    Serial.println("Camera sensor settings applied");
    startCameraServer_stream();
  }
  else Serial.print("Fail!");
}

void loop() {
  delay(1000);
}

int camera_cfg(){
  camera_config_t config;

  // Camera pins configuration for ESP32-S3 
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
/*FRAMESIZE_UXGA (1600 x 1200)
  FRAMESIZE_QVGA (320 x 240)
  FRAMESIZE_CIF (352 x 288)
  FRAMESIZE_VGA (640 x 480)
  FRAMESIZE_SVGA (800 x 600)
  FRAMESIZE_XGA (1024 x 768)
  FRAMESIZE_SXGA (1280 x 1024)*/
  config.frame_size = FRAMESIZE_VGA; //UXGA less quality -> frame too big, VGA and SBGA smaller frame better quality 
  config.pixel_format = PIXFORMAT_JPEG; // Medium quality video
  //config.pixel_format = PIXFORMAT_RGB565; // High quality video. Not working for capture
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; //good for picture, for video CAMERA_GRAB_LATEST
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 10; //The lower it is, the higher the quality
  config.fb_count = 2; //1-> best value so far. 2 and 3 not great

  // Initialize the camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.print("Camera init failed with error 0x");
    Serial.println(err, HEX);
    return 0;
  }
  Serial.println("Camera initialized");
  return 1;
}

void camera_settings(){ 
  
  sensor_t *s = esp_camera_sensor_get();
  if (!s) {
    Serial.println("Failed to get camera sensor");
    return;
  }

  //Additional sensor settings for better quality
  s->set_brightness(s, 0);     // -2 to 2
  s->set_contrast(s, 0);       // -2 to 2
  s->set_saturation(s, 0);     // -2 to 2
  s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
  s->set_whitebal(s, 1);       // 0 = disable , 1 = enable
  s->set_awb_gain(s, 1);       // 0 = disable , 1 = enable
  s->set_wb_mode(s, 0);        // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
  s->set_exposure_ctrl(s, 1);  // 0 = disable , 1 = enable
  s->set_aec2(s, 0);           // 0 = disable , 1 = enable
  s->set_ae_level(s, 0);       // -2 to 2
  s->set_aec_value(s, 300);    // 0 to 1200
  s->set_gain_ctrl(s, 1);      // 0 = disable , 1 = enable
  s->set_agc_gain(s, 0);       // 0 to 30
  s->set_gainceiling(s, (gainceiling_t)0);  // 0 to 6
  s->set_bpc(s, 0);            // 0 = disable , 1 = enable
  s->set_wpc(s, 1);            // 0 = disable , 1 = enable
  s->set_raw_gma(s, 1);        // 0 = disable , 1 = enable
  s->set_lenc(s, 1);           // 0 = disable , 1 = enable
  s->set_hmirror(s, 1);        // 0 = disable , 1 = enable
  s->set_vflip(s, 1);          // 0 = disable , 1 = enable
  s->set_dcw(s, 1);            // 0 = disable , 1 = enable
  s->set_colorbar(s, 0);       // 0 = disable , 1 = enable
}

void wifi(){

  WiFi.mode(WIFI_STA); //to make sure that it connects to a router
  WiFi.begin(ssid, password);
  delay(100);
  WiFi.setSleep(false); // to disable the Wi-Fi sleep mode. By default, the ESP32 might enter a sleep mode to conserve power when it’s not actively transmitting or receiving data.

  while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.print(".");
        Serial.print("Wifi-status: ");
        Serial.println(WiFi.status()); //Check wifi status
    }
    Serial.println("Connected to Wi-Fi");
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());
}

void startCameraServer_stream() { //for streaming video

  // Set up the server to stream MJPEG video
  server.on("/stream", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", 
      "<html><body><img src='/mjpeg_stream'></body></html>");
  });

  server.on("/mjpeg_stream", HTTP_GET, [](AsyncWebServerRequest *request){
    AsyncWebServerResponse *response = request->beginChunkedResponse("multipart/x-mixed-replace; boundary=frame", 
      [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
        camera_fb_t *fb = esp_camera_fb_get(); // Capture a frame from the camera
        if (!fb) {
          Serial.println("Camera capture failed");
          return 0;
        }

        size_t len = fb->len;
        if (len > maxLen) {
          len = maxLen;
        }
        memcpy(buffer, fb->buf, len); // Copy frame data to buffer
        esp_camera_fb_return(fb); // Return the frame buffer

        return len;
      });
      
    response->addHeader("Access-Control-Allow-Origin", "*");
    request->send(response);
  });

  server.begin();
  Serial.println("Camera server started"); //Use http://IP-address/stream for video 
}


Did you find a solution?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.