ArduCAM / Arduino

This is ArduCAM library for Arduino boards
MIT License
472 stars 348 forks source link

Async OV2640 Stream #180

Open MattGG opened 7 years ago

MattGG commented 7 years ago

Having some trouble getting the server stream and other html elements working at the same time and looking for some direction or advice on the best way to implement the stream and other html elements on the same page such that button and sliders are not blocked while streaming. At the moment if the stream is started server.on("/stream", HTTP_GET, serverStream); then web socket events will not fire. The html, javascript, web socket and web server are all on the ESP and the client connects via ddns address. Have been trying to get the ESPAsyncWebServer working with the Arducam but am having trouble sending the responses for example

void serverStream(){
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n";
server.sendContent(response);
.......
if (!client.connected()) break;
  response = "--frame\r\n";
  response += "Content-Type: image/jpeg\r\n\r\n";
  server.sendContent(response); 
........
}

to

void serverStream(AsyncWebServerRequest *request){
request->send(200, "text/plain", "HTTP/1.1 200 OK\r\nContent-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n");
....
request->send(200, "text/plain", "--frame\r\nContent-Type: image/jpeg\r\n\r\n");
.....
}

I feel like I am missing something obvious here, I would have thought a button onclick or slider onchnage web socket events while the video is streaming would be a common implementation.

Any advice would be great.

MattGG commented 7 years ago

I think we need to do something like the following

void serverStream(AsyncWebServerRequest *request){
   AsyncWebServerResponse *response = request->beginChunkedResponse( "text/html",  [](uint8_t *buffer, size_t maxlen, size_t index) -> size_t {
    size_t xlen=0;

    while (1){
      start_capture();
      while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
      size_t len = myCAM.read_fifo_length();
      if (len >= MAX_FIFO_SIZE) //8M
        {
        Serial.println(F("Over size."));
        continue;
        }
      if (len == 0 ) //0 kb
        {
        Serial.println(F("Size is 0."));
        continue;
        } 
      myCAM.CS_LOW();
      myCAM.set_fifo_burst();

      while ( len-- )
        {
        temp_last = temp;
        temp =  SPI.transfer(0x00);

        //Read JPEG data from FIFO
        if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
          {
          buffer[i++] = temp;  //save the last  0XD9     
          //Write the remain bytes in the buffer
          myCAM.CS_HIGH();; 
          xlen++;
          return xlen;
          is_header = false;
          i = 0;
          }  
        if (is_header == true)
          { 
          //Write image data to buffer if not full
          if (i < bufferSize)
          buffer[i++] = temp;
          else
          {
          //Write bufferSize bytes image data to file
          myCAM.CS_HIGH(); 
          xlen ++;
          return xlen;
          i = 0;
          buffer[i++] = temp;
          myCAM.CS_LOW();
          myCAM.set_fifo_burst();
          }        
          }
        else if ((temp == 0xD8) & (temp_last == 0xFF))
          {
          is_header = true;
          buffer[i++] = temp_last;
          buffer[i++] = temp;   
          } 
        }

       }
      });
      response->addHeader("Content-Type:", "image/jpeg\r\n\r\n");
      request->send(response);
}

Just not sure how to progress this, in the original web server code there are two responses and I'm just not sure how to pass those to the client with async and chunked response.

request->send(200, "text/plain", "HTTP/1.1 200 OK\r\nContent-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n");

request->send(200, "text/plain", "--frame\r\nContent-Type: image/jpeg\r\n\r\n");
mkeyno commented 6 years ago

@MattGG have you test video streaming with async library ?

crankyadmin commented 3 years ago

Sorry to raise this one from the dead, but I'm having the same issue. I've got to exactly the same point @MattGG got to. Any pointers would be gratefully received. Thanks

mkeyno commented 3 years ago

@crankyadmin I used board version 2, and this board design is totally false, and did not receive any support for this faulty board from @ArduCAM and I have to throw it away https://github.com/ArduCAM/Arduino/issues/468