Board: XIAO ESP32S3 (Sense)
UseCase: I would like to use a Arduino script to record both video and audio with the board, store them temporarily on the sd card and then send them via http post multipart/form-data to a server that processes the data further. The two files together are smaller than 1 megabyte.
Problem: Recording a video as an .avi file, recording audio as a .wav file and saving both files on the sd card works fine without any problems. The structure of the post request is also valid and works as well. In addition, the request contains a json generated in the script (sending the json as part of the request already works). However, I do not know how to attach the .avi and .wav file to the request. Simply adding the files as a string does not work.
Question: How can I send .avi and .wav as part of the http post multipart/form-data request? Is there a way to attach the files read directly from the SD card to the request?
Code example: Below you can find a minimal code example (Arduino) that establishes a wifi connection, retrieves the two files from the SD card, generates a json and sets up the request. What is missing is the way the files are sent with the request.
I am happy to hear about any suggestions for solutions.
- #include <WiFi.h>
- #include <HTTPClient.h>
- #include <ArduinoJson.h>
- const char* ssid = "...";
- const char* password = "...";
- const char* serverAddress = "...";
- const char* aviFilePath = "/video0.avi";
- const char* wavFilePath = "/arduino_rec.wav";
- //SD
- #include "FS.h"
- #include "SD.h"
- #include "SPI.h"
- const int SD_PIN_CS = 21;
- bool sd_sign = false;
- File videoFile;
- File audioFile;
- void setup() {
- Serial.begin(115200);
- // Connect to Wi-Fi
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(1000);
- Serial.println("Connecting to WiFi...");
- }
- Serial.println("Connected to WiFi");
- //Setup SD Card
- // Initialize the SD card
- if (!SD.begin(SD_PIN_CS)) {
- Serial.println("SD card initialization failed!");
- return;
- }
- uint8_t cardType = SD.cardType();
- // Determine if the type of SD card is available
- if(cardType == CARD_NONE){
- Serial.println("No SD card attached");
- return;
- }
- Serial.print("SD Card Type: ");
- if(cardType == CARD_MMC){
- Serial.println("MMC");
- } else if(cardType == CARD_SD){
- Serial.println("SDSC");
- } else if(cardType == CARD_SDHC){
- Serial.println("SDHC");
- } else {
- Serial.println("UNKNOWN");
- }
- sd_sign = true;
- }
- void loop() {
- if (SD.exists("/video0.avi") == 1 && SD.exists("/arduino_rec.wav") == 1) {
- videoFile = SD.open("/video0.avi", FILE_READ);
- audioFile = SD.open("/arduino_rec.wav", FILE_READ);
- if ((WiFi.status() == WL_CONNECTED)) { // Check Wi-Fi connection status
- StaticJsonDocument<96> movement;
- movement["start_date"] = "2024-03-08 16:03:10.210804";
- movement["end_date"] = "2024-03-08 16:04:10.210804";
- movement["audio"] = "audioKey";
- movement["video"] = "videoKey";
- String output;
- serializeJson(movement, output);
- HTTPClient http;
- http.begin(serverAddress);
- // Set headers for multipart/form-data
- String boundary = "----WebKitFormBoundary" + String(random(0xFFFFFF), HEX);
- http.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
- String requestBody = "------" + boundary + "\r\n";
- requestBody += "Content-Disposition: form-data; name=\"json\"\r\n\r\n";
- requestBody += output;
- requestBody += "\r\n";
- requestBody += "--" + boundary + "\r\n";
- requestBody += "Content-Disposition: form-data; name=\"videoKey\"; filename=\"video0.avi\"\r\n";
- requestBody += "Content-Type: video/avi\r\n\r\n";
- requestBody += videoFile.readString();
- requestBody += "\r\n";
- requestBody += "--" + boundary + "\r\n";
- requestBody += "Content-Disposition: form-data; name=\"audioKey\"; filename=\"arduino_rec.wav\"\r\n";
- requestBody += "Content-Type: audio/wav\r\n\r\n";
- requestBody += audioFile.readString();
- requestBody += "\r\n";
- requestBody += "--" + boundary + "--\r\n";
- // Calculate the content length
- int contentLength = requestBody.length();
- // Set the Content-Length header
- http.addHeader("Content-Length", String(contentLength));
- // Send the POST request
- int httpResponseCode = http.sendRequest("POST", requestBody);
- if (httpResponseCode == HTTP_CODE_OK) {
- Serial.println("Data sent successfully!");
- } else {
- Serial.print("Error sending data. HTTP code: ");
- Serial.println(httpResponseCode);
- }
- videoFile.close();
- audioFile.close();
- http.end();
- }
- }
- delay(10000);