mirror of
https://github.com/EyeTrackVR/OpenIris.git
synced 2025-11-04 15:39:42 +08:00
Rewrite the streaming back to http while keeping AsyncWebServer in charge of API, remove OTA update time limit (#19)
This commit is contained in:
parent
08bdb6d378
commit
78ac54bff8
@ -7,6 +7,7 @@
|
||||
#include "cameraHandler.h"
|
||||
extern char *MDSNTrackerName;
|
||||
extern int STREAM_SERVER_PORT;
|
||||
extern int CONTROL_SERVER_PORT;
|
||||
|
||||
extern OpenIris::LEDManager ledManager;
|
||||
extern OpenIris::StateManager stateManager;
|
||||
|
||||
@ -6,8 +6,7 @@ namespace OpenIris
|
||||
class OTA
|
||||
{
|
||||
private:
|
||||
unsigned long bootTimestamp = 0;
|
||||
bool isOtaEnabled = true;
|
||||
bool isOTAEnabled = false;
|
||||
|
||||
public:
|
||||
void SetupOTA(const char *OTAPassword, uint16_t OTAServerPort)
|
||||
@ -20,6 +19,7 @@ namespace OpenIris
|
||||
return;
|
||||
}
|
||||
ArduinoOTA.setPort(OTAServerPort);
|
||||
isOTAEnabled = true;
|
||||
|
||||
ArduinoOTA
|
||||
.onStart([]()
|
||||
@ -44,20 +44,12 @@ namespace OpenIris
|
||||
log_i("Starting up basic OTA server");
|
||||
log_i("OTA will be live for 30s, after which it will be disabled until restart");
|
||||
ArduinoOTA.begin();
|
||||
bootTimestamp = millis();
|
||||
}
|
||||
|
||||
void HandleOTAUpdate()
|
||||
{
|
||||
if (isOtaEnabled)
|
||||
if (isOTAEnabled)
|
||||
{
|
||||
if (bootTimestamp + 30000 < millis())
|
||||
{
|
||||
// we're disabling ota after first 30sec so that nothing bad happens during playtime
|
||||
isOtaEnabled = false;
|
||||
log_i("From now on, OTA is disabled");
|
||||
return;
|
||||
}
|
||||
ArduinoOTA.handle();
|
||||
}
|
||||
}
|
||||
|
||||
22
ESP/include/streamServer.h
Normal file
22
ESP/include/streamServer.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
#include <Arduino.h>
|
||||
#include "esp_camera.h"
|
||||
#include "esp_http_server.h"
|
||||
|
||||
namespace OpenIris
|
||||
{
|
||||
namespace StreamHelpers
|
||||
{
|
||||
esp_err_t stream(httpd_req_t *req);
|
||||
}
|
||||
class StreamServer
|
||||
{
|
||||
|
||||
private:
|
||||
httpd_handle_t camera_stream = nullptr;
|
||||
|
||||
public:
|
||||
int startStreamServer();
|
||||
};
|
||||
}
|
||||
@ -1,163 +0,0 @@
|
||||
#pragma once
|
||||
#include <AsyncTCP.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include "esp_camera.h"
|
||||
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
|
||||
namespace OpenIris
|
||||
{
|
||||
namespace WebServerHelpers
|
||||
{
|
||||
static const char *STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
|
||||
static const char *STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
|
||||
static const char *STREAM_PART = "Content-Type: %s\r\nContent-Length: %u\r\n\r\n";
|
||||
|
||||
static const char *JPG_CONTENT_TYPE = "image/jpeg";
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
camera_fb_t *fb;
|
||||
size_t index;
|
||||
} camera_frame_t;
|
||||
|
||||
class AsyncJpegStreamResponse : public AsyncAbstractResponse
|
||||
{
|
||||
private:
|
||||
camera_frame_t _frame;
|
||||
size_t _index;
|
||||
size_t _jpg_buf_len;
|
||||
uint8_t *_jpg_buf;
|
||||
long lastAsyncRequest;
|
||||
|
||||
public:
|
||||
AsyncJpegStreamResponse()
|
||||
{
|
||||
_callback = nullptr;
|
||||
_code = 200;
|
||||
_contentLength = 0;
|
||||
_contentType = OpenIris::WebServerHelpers::STREAM_CONTENT_TYPE;
|
||||
_sendContentLength = false;
|
||||
_chunked = true;
|
||||
_index = 0;
|
||||
_jpg_buf_len = 0;
|
||||
_jpg_buf = NULL;
|
||||
lastAsyncRequest = 0;
|
||||
memset(&_frame, 0, sizeof(camera_frame_t));
|
||||
}
|
||||
~AsyncJpegStreamResponse()
|
||||
{
|
||||
if (_frame.fb)
|
||||
{
|
||||
if (_frame.fb->format != PIXFORMAT_JPEG)
|
||||
{
|
||||
free(_jpg_buf);
|
||||
}
|
||||
esp_camera_fb_return(_frame.fb);
|
||||
}
|
||||
}
|
||||
bool _sourceValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override
|
||||
{
|
||||
size_t ret = _content(buf, maxLen, _index);
|
||||
if (ret != RESPONSE_TRY_AGAIN)
|
||||
{
|
||||
_index += ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t _content(uint8_t *buffer, size_t maxLen, size_t index)
|
||||
{
|
||||
if (!_frame.fb || _frame.index == _jpg_buf_len)
|
||||
{
|
||||
if (index && _frame.fb)
|
||||
{
|
||||
long end = millis();
|
||||
int fp = (end - lastAsyncRequest);
|
||||
log_d("Size: %uKB, Time: %ums (%ifps)\n", _jpg_buf_len / 1024, fp, 1000 / fp);
|
||||
lastAsyncRequest = end;
|
||||
if (_frame.fb->format != PIXFORMAT_JPEG)
|
||||
{
|
||||
free(_jpg_buf);
|
||||
}
|
||||
esp_camera_fb_return(_frame.fb);
|
||||
_frame.fb = NULL;
|
||||
_jpg_buf_len = 0;
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
if (maxLen < (strlen(OpenIris::WebServerHelpers::STREAM_BOUNDARY) + strlen(OpenIris::WebServerHelpers::STREAM_PART) + strlen(OpenIris::WebServerHelpers::JPG_CONTENT_TYPE) + 8))
|
||||
{
|
||||
// log_w("Not enough space for headers");
|
||||
return RESPONSE_TRY_AGAIN;
|
||||
}
|
||||
// get frame
|
||||
_frame.index = 0;
|
||||
|
||||
_frame.fb = esp_camera_fb_get();
|
||||
if (_frame.fb == NULL)
|
||||
{
|
||||
log_e("Camera frame failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_frame.fb->format != PIXFORMAT_JPEG)
|
||||
{
|
||||
unsigned long st = millis();
|
||||
bool jpeg_converted = frame2jpg(_frame.fb, 40, &_jpg_buf, &_jpg_buf_len);
|
||||
if (!jpeg_converted)
|
||||
{
|
||||
log_e("JPEG compression failed");
|
||||
esp_camera_fb_return(_frame.fb);
|
||||
_frame.fb = NULL;
|
||||
_jpg_buf_len = 0;
|
||||
_jpg_buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
log_i("JPEG: %lums, %uB", millis() - st, _jpg_buf_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
_jpg_buf_len = _frame.fb->len;
|
||||
_jpg_buf = _frame.fb->buf;
|
||||
}
|
||||
|
||||
// send boundary
|
||||
size_t blen = 0;
|
||||
if (index)
|
||||
{
|
||||
blen = strlen(OpenIris::WebServerHelpers::STREAM_BOUNDARY);
|
||||
memcpy(buffer, OpenIris::WebServerHelpers::STREAM_BOUNDARY, blen);
|
||||
buffer += blen;
|
||||
}
|
||||
// send header
|
||||
size_t hlen = sprintf((char *)buffer, OpenIris::WebServerHelpers::STREAM_PART, OpenIris::WebServerHelpers::JPG_CONTENT_TYPE, _jpg_buf_len);
|
||||
buffer += hlen;
|
||||
// send frame
|
||||
hlen = maxLen - hlen - blen;
|
||||
if (hlen > _jpg_buf_len)
|
||||
{
|
||||
maxLen -= hlen - _jpg_buf_len;
|
||||
hlen = _jpg_buf_len;
|
||||
}
|
||||
memcpy(buffer, _jpg_buf, hlen);
|
||||
_frame.index += hlen;
|
||||
return maxLen;
|
||||
}
|
||||
|
||||
size_t available = _jpg_buf_len - _frame.index;
|
||||
if (maxLen > available)
|
||||
{
|
||||
maxLen = available;
|
||||
}
|
||||
memcpy(buffer, _jpg_buf + _frame.index, maxLen);
|
||||
_frame.index += maxLen;
|
||||
|
||||
return maxLen;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
#include <AsyncTCP.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include "esp_camera.h"
|
||||
|
||||
namespace OpenIris
|
||||
{
|
||||
class HTTPDHandler
|
||||
{
|
||||
private:
|
||||
void command_handler(AsyncWebServerRequest *request);
|
||||
void stream_handler(AsyncWebServerRequest *request);
|
||||
void roi_crop_command_handler(AsyncWebServerRequest *request);
|
||||
AsyncWebServer *server;
|
||||
|
||||
public:
|
||||
HTTPDHandler();
|
||||
void startStreamServer();
|
||||
};
|
||||
}
|
||||
21
ESP/include/webserverHandler.h
Normal file
21
ESP/include/webserverHandler.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#define WEBSERVER_H
|
||||
#define HTTP_ANY 0b01111111
|
||||
#define HTTP_GET 0b00000001
|
||||
#include <AsyncTCP.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
namespace OpenIris
|
||||
{
|
||||
class APIServer
|
||||
{
|
||||
private:
|
||||
void command_handler(AsyncWebServerRequest *request);
|
||||
AsyncWebServer *server;
|
||||
|
||||
public:
|
||||
APIServer();
|
||||
void startAPIServer();
|
||||
};
|
||||
}
|
||||
@ -22,9 +22,9 @@ int OpenIris::CameraHandler::setupCamera()
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 20000000; //10000000 stable,
|
||||
//16500000 optimal,
|
||||
//20000000 max fps
|
||||
config.xclk_freq_hz = 20000000; // 10000000 stable,
|
||||
// 16500000 optimal,
|
||||
// 20000000 max fps
|
||||
config.pixel_format = PIXFORMAT_JPEG;
|
||||
|
||||
if (psramFound())
|
||||
@ -52,7 +52,7 @@ int OpenIris::CameraHandler::setupCamera()
|
||||
camera_sensor->set_contrast(camera_sensor, 2); // -2 to 2
|
||||
camera_sensor->set_saturation(camera_sensor, -2); // -2 to 2
|
||||
camera_sensor->set_whitebal(camera_sensor, 1); // 0 = disable , 1 = enable
|
||||
camera_sensor->set_awb_gain(camera_sensor, 1); // 0 = disable , 1 = enable
|
||||
camera_sensor->set_awb_gain(camera_sensor, 1); // 0 = disable , 1 = enable
|
||||
camera_sensor->set_wb_mode(camera_sensor, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
|
||||
camera_sensor->set_exposure_ctrl(camera_sensor, 1); // 0 = disable , 1 = enable
|
||||
camera_sensor->set_aec2(camera_sensor, 0); // 0 = disable , 1 = enable
|
||||
|
||||
@ -5,29 +5,34 @@
|
||||
#include "MDNSManager.h"
|
||||
#include "cameraHandler.h"
|
||||
#include "LEDManager.h"
|
||||
#include "webServer/webserverHandler.h"
|
||||
#include "streamServer.h"
|
||||
#include "webserverHandler.h"
|
||||
|
||||
#include "OTA.h"
|
||||
#include "StateManager.h"
|
||||
|
||||
char *MDSNTrackerName = "OpenIrisTracker";
|
||||
const char *MDSNTrackerName = "OpenIrisTracker";
|
||||
|
||||
int STREAM_SERVER_PORT = 80;
|
||||
int CONTROL_SERVER_PORT = 81;
|
||||
|
||||
auto ota = OpenIris::OTA();
|
||||
auto ledManager = OpenIris::LEDManager(33);
|
||||
auto cameraHandler = OpenIris::CameraHandler();
|
||||
auto stateManager = OpenIris::StateManager();
|
||||
auto httpdHandler = OpenIris::HTTPDHandler();
|
||||
auto apiServer = OpenIris::APIServer();
|
||||
auto streamServer = OpenIris::StreamServer();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Serial.println();
|
||||
ledManager.setupLED();
|
||||
cameraHandler.setupCamera();
|
||||
OpenIris::WiFiHandler::setupWifi(ssid, password);
|
||||
OpenIris::MDNSHandler::setupMDNS();
|
||||
httpdHandler.startStreamServer();
|
||||
apiServer.startAPIServer();
|
||||
streamServer.startStreamServer();
|
||||
ledManager.on();
|
||||
|
||||
ota.SetupOTA(OTAPassword, OTAServerPort);
|
||||
|
||||
109
ESP/src/streamServer.cpp
Normal file
109
ESP/src/streamServer.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include "streamServer.h"
|
||||
#include "GlobalVars.h"
|
||||
|
||||
constexpr static char *STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
|
||||
constexpr static char *STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
|
||||
constexpr static char *STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\nX-Timestamp: %d.%06d\r\n\r\n";
|
||||
|
||||
esp_err_t OpenIris::StreamHelpers::stream(httpd_req_t *req)
|
||||
{
|
||||
long last_request_time = 0;
|
||||
camera_fb_t *fb = NULL;
|
||||
struct timeval _timestamp;
|
||||
|
||||
esp_err_t res = ESP_OK;
|
||||
|
||||
size_t _jpg_buf_len = 0;
|
||||
uint8_t *_jpg_buf = NULL;
|
||||
|
||||
char *part_buf[128];
|
||||
|
||||
static int64_t last_frame = 0;
|
||||
if (!last_frame)
|
||||
last_frame = esp_timer_get_time();
|
||||
|
||||
res = httpd_resp_set_type(req, STREAM_CONTENT_TYPE);
|
||||
if (res != ESP_OK)
|
||||
return res;
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin; Content-Type: multipart/x-mixed-replace; boundary=123456789000000000000987654321\r\n", "*");
|
||||
httpd_resp_set_hdr(req, "X-Framerate", "60");
|
||||
|
||||
while (true)
|
||||
{
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb)
|
||||
{
|
||||
log_e("Camera capture failed");
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_timestamp.tv_sec = fb->timestamp.tv_sec;
|
||||
_timestamp.tv_usec = fb->timestamp.tv_usec;
|
||||
_jpg_buf_len = fb->len;
|
||||
_jpg_buf = fb->buf;
|
||||
}
|
||||
|
||||
if (res == ESP_OK)
|
||||
res = httpd_resp_send_chunk(req, STREAM_BOUNDARY, strlen(STREAM_BOUNDARY));
|
||||
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
size_t hlen = snprintf((char *)part_buf, 128, STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec);
|
||||
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
|
||||
}
|
||||
if (res == ESP_OK)
|
||||
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
|
||||
|
||||
if (fb)
|
||||
{
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
|
||||
else if (_jpg_buf)
|
||||
{
|
||||
free(_jpg_buf);
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
|
||||
if (res != ESP_OK)
|
||||
break;
|
||||
|
||||
long request_end = millis();
|
||||
long latency = (request_end - last_request_time);
|
||||
last_request_time = request_end;
|
||||
log_d("Size: %uKB, Time: %ums (%ifps)\n", _jpg_buf_len / 1024, latency, 1000 / latency);
|
||||
}
|
||||
|
||||
last_frame = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int OpenIris::StreamServer::startStreamServer()
|
||||
{
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.max_uri_handlers = 1;
|
||||
config.server_port = STREAM_SERVER_PORT;
|
||||
config.ctrl_port = STREAM_SERVER_PORT;
|
||||
|
||||
httpd_uri_t stream_page = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = &OpenIris::StreamHelpers::stream,
|
||||
.user_ctx = nullptr};
|
||||
|
||||
int status = httpd_start(&camera_stream, &config);
|
||||
|
||||
if (status != ESP_OK)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
httpd_register_uri_handler(camera_stream, &stream_page);
|
||||
log_d("Stream server initialized");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
#include "GlobalVars.h"
|
||||
#include "webServer/asyncJPGResponse.h"
|
||||
#include "webServer/webserverHandler.h"
|
||||
|
||||
OpenIris::HTTPDHandler::HTTPDHandler()
|
||||
{
|
||||
this->server = new AsyncWebServer(STREAM_SERVER_PORT);
|
||||
}
|
||||
|
||||
void OpenIris::HTTPDHandler::startStreamServer()
|
||||
{
|
||||
this->server->on(
|
||||
"/",
|
||||
HTTP_GET,
|
||||
std::bind(&OpenIris::HTTPDHandler::stream_handler, this, std::placeholders::_1));
|
||||
this->server->on(
|
||||
"/control",
|
||||
HTTP_GET,
|
||||
std::bind(&OpenIris::HTTPDHandler::command_handler, this, std::placeholders::_1));
|
||||
|
||||
this->server->on(
|
||||
"/crop-roi",
|
||||
HTTP_GET,
|
||||
std::bind(&OpenIris::HTTPDHandler::roi_crop_command_handler, this, std::placeholders::_1));
|
||||
|
||||
log_d("Initializing web server");
|
||||
this->server->begin();
|
||||
}
|
||||
|
||||
void OpenIris::HTTPDHandler::roi_crop_command_handler(AsyncWebServerRequest *request)
|
||||
{
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
int outputX = 0;
|
||||
int outputY = 0;
|
||||
|
||||
if (request->hasParam("offsetX"))
|
||||
{
|
||||
AsyncWebParameter *offsetX_param = request->getParam("offsetX");
|
||||
offsetX = atoi(offsetX_param->value().c_str());
|
||||
}
|
||||
if (request->hasParam("offsetY"))
|
||||
{
|
||||
AsyncWebParameter *offsetY_param = request->getParam("offsetY");
|
||||
offsetY = atoi(offsetY_param->value().c_str());
|
||||
}
|
||||
if (request->hasParam("outputX"))
|
||||
{
|
||||
AsyncWebParameter *outputX_param = request->getParam("outputX");
|
||||
outputX = atoi(outputX_param->value().c_str());
|
||||
}
|
||||
if (request->hasParam("outputY"))
|
||||
{
|
||||
AsyncWebParameter *outputY_param = request->getParam("outputY");
|
||||
outputY = atoi(outputY_param->value().c_str());
|
||||
}
|
||||
|
||||
if (offsetX != 0 && offsetY != 0 && outputX != 0 && outputY != 0)
|
||||
cameraHandler.setVieWindow(offsetX, offsetY, outputX, outputY);
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void OpenIris::HTTPDHandler::command_handler(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (request->hasParam("framesize"))
|
||||
{
|
||||
AsyncWebParameter *framesize_param = request->getParam("framesize");
|
||||
cameraHandler.setCameraResolution((framesize_t)atoi(framesize_param->value().c_str()));
|
||||
}
|
||||
if (request->hasParam("hmirror"))
|
||||
{
|
||||
AsyncWebParameter *hmirror_param = request->getParam("hmirror");
|
||||
cameraHandler.setHFlip(atoi(hmirror_param->value().c_str()));
|
||||
}
|
||||
if (request->hasParam("vflip"))
|
||||
{
|
||||
AsyncWebParameter *vflip_param = request->getParam("vflip");
|
||||
cameraHandler.setVFlip(atoi(vflip_param->value().c_str()));
|
||||
}
|
||||
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void OpenIris::HTTPDHandler::stream_handler(AsyncWebServerRequest *request)
|
||||
{
|
||||
OpenIris::AsyncJpegStreamResponse *response = new OpenIris::AsyncJpegStreamResponse();
|
||||
if (!response)
|
||||
{
|
||||
request->send(501);
|
||||
return;
|
||||
}
|
||||
response->addHeader("Access-Control-Allow-Origin", "*");
|
||||
request->send(response);
|
||||
}
|
||||
39
ESP/src/webserverHandler.cpp
Normal file
39
ESP/src/webserverHandler.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "GlobalVars.h"
|
||||
#include "webserverHandler.h"
|
||||
|
||||
OpenIris::APIServer::APIServer()
|
||||
{
|
||||
this->server = new AsyncWebServer(CONTROL_SERVER_PORT);
|
||||
}
|
||||
|
||||
void OpenIris::APIServer::startAPIServer()
|
||||
{
|
||||
this->server->on(
|
||||
"/control",
|
||||
HTTP_GET,
|
||||
std::bind(&OpenIris::APIServer::command_handler, this, std::placeholders::_1));
|
||||
|
||||
log_d("Initializing web server");
|
||||
this->server->begin();
|
||||
}
|
||||
|
||||
void OpenIris::APIServer::command_handler(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (request->hasParam("framesize"))
|
||||
{
|
||||
AsyncWebParameter *framesize_param = request->getParam("framesize");
|
||||
cameraHandler.setCameraResolution((framesize_t)atoi(framesize_param->value().c_str()));
|
||||
}
|
||||
if (request->hasParam("hmirror"))
|
||||
{
|
||||
AsyncWebParameter *hmirror_param = request->getParam("hmirror");
|
||||
cameraHandler.setHFlip(atoi(hmirror_param->value().c_str()));
|
||||
}
|
||||
if (request->hasParam("vflip"))
|
||||
{
|
||||
AsyncWebParameter *vflip_param = request->getParam("vflip");
|
||||
cameraHandler.setVFlip(atoi(vflip_param->value().c_str()));
|
||||
}
|
||||
|
||||
request->send(200);
|
||||
}
|
||||
@ -27,7 +27,7 @@ void OpenIris::WiFiHandler::setupWifi(const char *ssid, const char *password)
|
||||
delay(1600);
|
||||
log_i("\n\rWiFi connected\n\r");
|
||||
log_i("ESP will be streaming under 'http://%s:80/\r\n", WiFi.localIP().toString().c_str());
|
||||
log_i("ESP will be accepting commands under 'http://%s:80/control\r\n", WiFi.localIP().toString().c_str());
|
||||
log_i("ESP will be accepting commands under 'http://%s:81/control\r\n", WiFi.localIP().toString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user