commit
234e17bf48
|
@ -1 +1 @@
|
||||||
Subproject commit 113629b1cf8769f65c09db0c3577a597e652860b
|
Subproject commit 67cf2403c01cfbecc0ea6ca7c662903cc2015384
|
|
@ -1,5 +1,6 @@
|
||||||
set(COMPONENT_SRCS "app_main.c" "app_wifi.c" "app_camera.c" "app_httpd.c")
|
set(COMPONENT_SRCS "app_main.c" "app_wifi.c" "app_camera.c" "app_httpd.c")
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||||
|
|
||||||
set(COMPONENT_REQUIRES
|
set(COMPONENT_REQUIRES
|
||||||
esp32-camera
|
esp32-camera
|
||||||
esp-face
|
esp-face
|
||||||
|
@ -7,4 +8,9 @@ set(COMPONENT_REQUIRES
|
||||||
esp_http_server
|
esp_http_server
|
||||||
fb_gfx
|
fb_gfx
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(COMPONENT_EMBED_FILES
|
||||||
|
"www/index_ov2640.html.gz"
|
||||||
|
"www/index_ov3660.html.gz")
|
||||||
|
|
||||||
register_component()
|
register_component()
|
||||||
|
|
|
@ -26,8 +26,10 @@ config ESP_WIFI_AP_PASSWORD
|
||||||
AP password for WPA2 or empty for Open.
|
AP password for WPA2 or empty for Open.
|
||||||
|
|
||||||
config SERVER_IP
|
config SERVER_IP
|
||||||
string "IP address of server"
|
string "WiFi AP IP Address"
|
||||||
default "192.168.4.1"
|
default "192.168.4.1"
|
||||||
|
help
|
||||||
|
IP address that the ESP will assign to it's AP interface. You can use this IP to connect to the camera after flashing.
|
||||||
|
|
||||||
config ESP_MAXIMUM_RETRY
|
config ESP_MAXIMUM_RETRY
|
||||||
int "Maximum retry"
|
int "Maximum retry"
|
||||||
|
@ -49,6 +51,8 @@ config CAMERA_MODEL_ESP_EYE
|
||||||
bool "ESP_EYE DevKit"
|
bool "ESP_EYE DevKit"
|
||||||
config CAMERA_MODEL_M5STACK_PSRAM
|
config CAMERA_MODEL_M5STACK_PSRAM
|
||||||
bool "M5Stack Camera With PSRAM"
|
bool "M5Stack Camera With PSRAM"
|
||||||
|
config CAMERA_MODEL_M5STACK_WIDE
|
||||||
|
bool "M5Stack Camera F (Wide)"
|
||||||
config CAMERA_MODEL_AI_THINKER
|
config CAMERA_MODEL_AI_THINKER
|
||||||
bool "ESP32-CAM by AI-Thinker"
|
bool "ESP32-CAM by AI-Thinker"
|
||||||
config CAMERA_MODEL_CUSTOM
|
config CAMERA_MODEL_CUSTOM
|
||||||
|
|
|
@ -77,7 +77,13 @@ void app_camera_main ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//drop down frame size for higher initial frame rate
|
|
||||||
sensor_t * s = esp_camera_sensor_get();
|
sensor_t * s = esp_camera_sensor_get();
|
||||||
|
//initial sensors are flipped vertically and colors are a bit saturated
|
||||||
|
if (s->id.PID == OV3660_PID) {
|
||||||
|
s->set_vflip(s, 1);//flip it back
|
||||||
|
s->set_brightness(s, 1);//up the blightness just a bit
|
||||||
|
s->set_saturation(s, -2);//lower the saturation
|
||||||
|
}
|
||||||
|
//drop down frame size for higher initial frame rate
|
||||||
s->set_framesize(s, FRAMESIZE_QVGA);
|
s->set_framesize(s, FRAMESIZE_QVGA);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "esp_camera.h"
|
#include "esp_camera.h"
|
||||||
#include "img_converters.h"
|
#include "img_converters.h"
|
||||||
#include "fb_gfx.h"
|
#include "fb_gfx.h"
|
||||||
#include "camera_index.h"
|
//#include "camera_index.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
|
||||||
|
@ -598,6 +598,7 @@ static esp_err_t status_handler(httpd_req_t *req){
|
||||||
p+=sprintf(p, "\"brightness\":%d,", s->status.brightness);
|
p+=sprintf(p, "\"brightness\":%d,", s->status.brightness);
|
||||||
p+=sprintf(p, "\"contrast\":%d,", s->status.contrast);
|
p+=sprintf(p, "\"contrast\":%d,", s->status.contrast);
|
||||||
p+=sprintf(p, "\"saturation\":%d,", s->status.saturation);
|
p+=sprintf(p, "\"saturation\":%d,", s->status.saturation);
|
||||||
|
p+=sprintf(p, "\"sharpness\":%d,", s->status.sharpness);
|
||||||
p+=sprintf(p, "\"special_effect\":%u,", s->status.special_effect);
|
p+=sprintf(p, "\"special_effect\":%u,", s->status.special_effect);
|
||||||
p+=sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode);
|
p+=sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode);
|
||||||
p+=sprintf(p, "\"awb\":%u,", s->status.awb);
|
p+=sprintf(p, "\"awb\":%u,", s->status.awb);
|
||||||
|
@ -632,9 +633,22 @@ static esp_err_t status_handler(httpd_req_t *req){
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t index_handler(httpd_req_t *req){
|
static esp_err_t index_handler(httpd_req_t *req){
|
||||||
|
extern const unsigned char index_ov2640_html_gz_start[] asm("_binary_index_ov2640_html_gz_start");
|
||||||
|
extern const unsigned char index_ov2640_html_gz_end[] asm("_binary_index_ov2640_html_gz_end");
|
||||||
|
size_t index_ov2640_html_gz_len = index_ov2640_html_gz_end - index_ov2640_html_gz_start;
|
||||||
|
|
||||||
|
extern const unsigned char index_ov3660_html_gz_start[] asm("_binary_index_ov3660_html_gz_start");
|
||||||
|
extern const unsigned char index_ov3660_html_gz_end[] asm("_binary_index_ov3660_html_gz_end");
|
||||||
|
size_t index_ov3660_html_gz_len = index_ov3660_html_gz_end - index_ov3660_html_gz_start;
|
||||||
|
|
||||||
|
|
||||||
httpd_resp_set_type(req, "text/html");
|
httpd_resp_set_type(req, "text/html");
|
||||||
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||||
return httpd_resp_send(req, (const char *)index_html_gz, index_html_gz_len);
|
sensor_t * s = esp_camera_sensor_get();
|
||||||
|
if (s->id.PID == OV3660_PID) {
|
||||||
|
return httpd_resp_send(req, (const char *)index_ov3660_html_gz_start, index_ov3660_html_gz_len);
|
||||||
|
}
|
||||||
|
return httpd_resp_send(req, (const char *)index_ov2640_html_gz_start, index_ov3660_html_gz_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_httpd_main(){
|
void app_httpd_main(){
|
||||||
|
|
|
@ -6,4 +6,5 @@
|
||||||
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
||||||
# please read the SDK documents if you need to do this.
|
# please read the SDK documents if you need to do this.
|
||||||
#
|
#
|
||||||
|
COMPONENT_EMBED_FILES := www/index_ov2640.html.gz
|
||||||
|
COMPONENT_EMBED_FILES += www/index_ov3660.html.gz
|
||||||
|
|
|
@ -81,6 +81,25 @@
|
||||||
#define HREF_GPIO_NUM 26
|
#define HREF_GPIO_NUM 26
|
||||||
#define PCLK_GPIO_NUM 21
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
|
#elif CONFIG_CAMERA_MODEL_M5STACK_WIDE
|
||||||
|
#define PWDN_GPIO_NUM -1
|
||||||
|
#define RESET_GPIO_NUM 15
|
||||||
|
#define XCLK_GPIO_NUM 27
|
||||||
|
#define SIOD_GPIO_NUM 22
|
||||||
|
#define SIOC_GPIO_NUM 23
|
||||||
|
|
||||||
|
#define Y9_GPIO_NUM 19
|
||||||
|
#define Y8_GPIO_NUM 36
|
||||||
|
#define Y7_GPIO_NUM 18
|
||||||
|
#define Y6_GPIO_NUM 39
|
||||||
|
#define Y5_GPIO_NUM 5
|
||||||
|
#define Y4_GPIO_NUM 34
|
||||||
|
#define Y3_GPIO_NUM 35
|
||||||
|
#define Y2_GPIO_NUM 32
|
||||||
|
#define VSYNC_GPIO_NUM 25
|
||||||
|
#define HREF_GPIO_NUM 26
|
||||||
|
#define PCLK_GPIO_NUM 21
|
||||||
|
|
||||||
#elif CONFIG_CAMERA_MODEL_AI_THINKER
|
#elif CONFIG_CAMERA_MODEL_AI_THINKER
|
||||||
#define PWDN_GPIO_NUM 32
|
#define PWDN_GPIO_NUM 32
|
||||||
#define RESET_GPIO_NUM -1
|
#define RESET_GPIO_NUM -1
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
|
|
||||||
//File: index.html.gz, Size: 3663
|
|
||||||
#define index_html_gz_len 3663
|
|
||||||
const uint8_t index_html_gz[] = {
|
|
||||||
0x1F, 0x8B, 0x08, 0x08, 0x60, 0x15, 0x36, 0x5C, 0x00, 0x03, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x2E,
|
|
||||||
0x68, 0x74, 0x6D, 0x6C, 0x00, 0xDD, 0x5C, 0xEB, 0x72, 0x9B, 0xC8, 0x12, 0xFE, 0x7F, 0x9E, 0x02,
|
|
||||||
0x93, 0xDD, 0x08, 0x6A, 0x91, 0x2C, 0xC9, 0x8A, 0xE3, 0x20, 0x0B, 0x1F, 0x5B, 0x76, 0x92, 0xAD,
|
|
||||||
0xCA, 0x6D, 0xE3, 0x3D, 0xBB, 0x5B, 0xB5, 0xB5, 0x95, 0x8C, 0x60, 0x90, 0x26, 0x46, 0x8C, 0x02,
|
|
||||||
0x83, 0x2E, 0xD1, 0xF2, 0x1C, 0xE7, 0x81, 0xCE, 0x8B, 0x9D, 0x9E, 0x19, 0x40, 0xA0, 0x8B, 0x65,
|
|
||||||
0x49, 0x89, 0x94, 0x5A, 0xBB, 0xCA, 0x1A, 0xA0, 0xBB, 0xA7, 0xBB, 0xBF, 0xBE, 0x0C, 0x88, 0xF1,
|
|
||||||
0xF9, 0x91, 0x43, 0x6D, 0x36, 0x19, 0x60, 0xA5, 0xC7, 0xFA, 0x9E, 0xF5, 0xAF, 0x73, 0xF9, 0xA1,
|
|
||||||
0xC0, 0xCF, 0x79, 0x0F, 0x23, 0x47, 0x0E, 0xC5, 0x61, 0x1F, 0x33, 0xA4, 0xD8, 0x3D, 0x14, 0x84,
|
|
||||||
0x98, 0xB5, 0xD4, 0x88, 0xB9, 0xE5, 0x33, 0x75, 0xFE, 0xB2, 0x8F, 0xFA, 0xB8, 0xA5, 0x0E, 0x09,
|
|
||||||
0x1E, 0x0D, 0x68, 0xC0, 0x54, 0xC5, 0xA6, 0x3E, 0xC3, 0x3E, 0x90, 0x8F, 0x88, 0xC3, 0x7A, 0x2D,
|
|
||||||
0x07, 0x0F, 0x89, 0x8D, 0xCB, 0xE2, 0xC0, 0x20, 0x3E, 0x61, 0x04, 0x79, 0xE5, 0xD0, 0x46, 0x1E,
|
|
||||||
0x6E, 0xD5, 0xF2, 0xB2, 0x18, 0x61, 0x1E, 0xB6, 0x6E, 0x6E, 0xDF, 0x9D, 0xD4, 0x95, 0xB7, 0xBF,
|
|
||||||
0xD5, 0x1B, 0xA7, 0xD5, 0xF3, 0x63, 0x79, 0x6E, 0x46, 0x13, 0xB2, 0x09, 0x3F, 0xEE, 0x50, 0x67,
|
|
||||||
0x32, 0x75, 0x61, 0x9A, 0xB2, 0x8B, 0xFA, 0xC4, 0x9B, 0x98, 0x97, 0x01, 0x08, 0x35, 0x5E, 0x62,
|
|
||||||
0x6F, 0x88, 0x19, 0xB1, 0x91, 0x11, 0x22, 0x3F, 0x2C, 0x87, 0x38, 0x20, 0x6E, 0xB3, 0x83, 0xEC,
|
|
||||||
0xBB, 0x6E, 0x40, 0x23, 0xDF, 0x31, 0x1F, 0xD5, 0xCE, 0xF8, 0x6F, 0xD3, 0xA6, 0x1E, 0x0D, 0xCC,
|
|
||||||
0x47, 0x37, 0xCF, 0xF9, 0x6F, 0x53, 0xC8, 0x09, 0xC9, 0x17, 0x6C, 0xD6, 0x4E, 0x07, 0xE3, 0xB8,
|
|
||||||
0x57, 0x9F, 0xE6, 0xCE, 0x9C, 0xC1, 0x99, 0x10, 0xDB, 0x8C, 0x50, 0xBF, 0xD2, 0x47, 0xC4, 0x9F,
|
|
||||||
0x3A, 0x24, 0x1C, 0x78, 0x68, 0x62, 0xBA, 0x1E, 0x1E, 0xC7, 0x8F, 0xFA, 0xD8, 0x8F, 0x8C, 0xC2,
|
|
||||||
0x75, 0x7E, 0xBE, 0xEC, 0x90, 0x40, 0x9E, 0x33, 0x61, 0xAA, 0xA8, 0xEF, 0x4B, 0xC2, 0x8C, 0xD7,
|
|
||||||
0xA7, 0x3E, 0x6E, 0x0A, 0xC2, 0x51, 0x80, 0x06, 0x70, 0xC8, 0x3F, 0x9A, 0x7D, 0xE2, 0x4B, 0x27,
|
|
||||||
0x99, 0x27, 0x8D, 0xEA, 0x60, 0x5C, 0x50, 0xFC, 0xE4, 0x94, 0xFF, 0x36, 0x07, 0xC8, 0x71, 0x88,
|
|
||||||
0xDF, 0x35, 0xCF, 0xF8, 0x65, 0x1A, 0x38, 0x38, 0x28, 0x07, 0xC8, 0x21, 0x51, 0x68, 0x36, 0xE0,
|
|
||||||
0x4C, 0x1F, 0x05, 0x5D, 0x90, 0xC1, 0xE8, 0xC0, 0x2C, 0xD7, 0xAA, 0xB3, 0x13, 0x01, 0xE9, 0xF6,
|
|
||||||
0x98, 0xC9, 0xCF, 0xC4, 0x8F, 0x12, 0x6C, 0x0A, 0x66, 0xE4, 0x54, 0x11, 0x8A, 0x20, 0x8F, 0x74,
|
|
||||||
0xFD, 0x32, 0x61, 0xB8, 0x1F, 0x9A, 0x21, 0x0B, 0x30, 0xB3, 0x7B, 0xB1, 0x4B, 0xBA, 0x51, 0x80,
|
|
||||||
0xA7, 0xA9, 0x02, 0xD5, 0x44, 0x36, 0x0C, 0xCA, 0x23, 0xDC, 0xB9, 0x23, 0xAC, 0x9C, 0x4C, 0xD6,
|
|
||||||
0xC1, 0x2E, 0x0D, 0x70, 0x46, 0x50, 0xEE, 0x78, 0xD4, 0xBE, 0x2B, 0x87, 0x0C, 0x05, 0x6C, 0x91,
|
|
||||||
0x18, 0xB9, 0x0C, 0x07, 0xF3, 0xB4, 0x18, 0x0C, 0x5E, 0xA0, 0x4C, 0x05, 0x24, 0x87, 0xC4, 0xF7,
|
|
||||||
0x88, 0x8F, 0x57, 0x89, 0x95, 0x12, 0x8A, 0xA4, 0xE2, 0x5C, 0x62, 0x86, 0x42, 0xFA, 0xDD, 0xCC,
|
|
||||||
0x03, 0x62, 0xD2, 0xA6, 0x74, 0x7C, 0xAD, 0x5A, 0xFD, 0xB1, 0xD9, 0xC3, 0xC2, 0x5F, 0x28, 0x62,
|
|
||||||
0xF4, 0x7E, 0x27, 0xF3, 0xD8, 0xF8, 0x77, 0x1F, 0x3B, 0x04, 0x29, 0xDA, 0x0C, 0x3C, 0xE5, 0xAC,
|
|
||||||
0x0A, 0x9E, 0xD6, 0x15, 0xE4, 0x3B, 0x8A, 0x46, 0x03, 0x02, 0xDE, 0x46, 0x22, 0x14, 0x3C, 0x38,
|
|
||||||
0x03, 0x61, 0x3F, 0xC0, 0xFA, 0x74, 0x1D, 0x0C, 0x49, 0x44, 0xAC, 0x06, 0x62, 0x89, 0x05, 0x7D,
|
|
||||||
0x34, 0x2E, 0xE7, 0xAC, 0xE0, 0x87, 0x89, 0x25, 0x90, 0x6A, 0xB6, 0x06, 0x27, 0x87, 0x3D, 0xA5,
|
|
||||||
0xAC, 0xF0, 0xD0, 0xD2, 0x13, 0x73, 0x85, 0x89, 0x39, 0x73, 0xFF, 0x29, 0x28, 0xA7, 0x19, 0xFB,
|
|
||||||
0xA8, 0x13, 0x31, 0x46, 0xFD, 0x70, 0x8D, 0x9B, 0x3F, 0x45, 0x21, 0x23, 0xEE, 0xA4, 0x9C, 0x80,
|
|
||||||
0x62, 0x86, 0x03, 0x04, 0xF5, 0xAA, 0x83, 0xD9, 0x08, 0x63, 0x48, 0x5D, 0x1F, 0x0D, 0x01, 0xEE,
|
|
||||||
0x6E, 0xD7, 0xC3, 0x53, 0x3B, 0x0A, 0x42, 0xA8, 0x1C, 0x03, 0x4A, 0x80, 0x32, 0x68, 0x16, 0x00,
|
|
||||||
0xC8, 0x13, 0x96, 0xED, 0xCE, 0x94, 0x46, 0x8C, 0xAB, 0x04, 0x2A, 0x52, 0x90, 0x47, 0xD8, 0x04,
|
|
||||||
0x46, 0xD2, 0xED, 0xD5, 0xD4, 0xE7, 0xD5, 0x39, 0x1E, 0xD3, 0xEE, 0x61, 0xFB, 0x0E, 0x3B, 0x3F,
|
|
||||||
0x15, 0xCB, 0x85, 0x28, 0x35, 0x15, 0xE2, 0x0F, 0x22, 0x56, 0xE6, 0x05, 0x61, 0xB0, 0xC6, 0x1E,
|
|
||||||
0xE1, 0x89, 0x64, 0x8A, 0x7A, 0x3D, 0x8B, 0x59, 0xF3, 0xC9, 0x60, 0xAC, 0x54, 0x0B, 0x82, 0x2C,
|
|
||||||
0x0F, 0x75, 0xB0, 0x97, 0x89, 0x4B, 0x9C, 0x28, 0xE3, 0x29, 0x09, 0x82, 0x5C, 0xF5, 0xC8, 0x55,
|
|
||||||
0xA8, 0xC6, 0xD3, 0x1F, 0x0B, 0x82, 0x14, 0x31, 0x36, 0x0A, 0xA7, 0x42, 0xEC, 0x01, 0x0C, 0xB2,
|
|
||||||
0x20, 0xC2, 0x99, 0x91, 0x59, 0x8B, 0x2B, 0x01, 0xF2, 0xBB, 0x18, 0x00, 0x1C, 0x1B, 0xE9, 0x30,
|
|
||||||
0x57, 0x52, 0x97, 0x4D, 0x6F, 0x56, 0x15, 0x50, 0x3B, 0x96, 0x40, 0x2E, 0x44, 0x7C, 0x6A, 0x56,
|
|
||||||
0x8E, 0xBA, 0x56, 0xCF, 0x6A, 0x23, 0x38, 0xBA, 0xE0, 0x0A, 0x5E, 0x35, 0xE7, 0x10, 0x4C, 0x3A,
|
|
||||||
0x81, 0xEB, 0x16, 0xFB, 0x84, 0xEB, 0x9E, 0x54, 0x4F, 0x1A, 0x73, 0xD9, 0xCF, 0xE7, 0x29, 0xF6,
|
|
||||||
0x8A, 0x66, 0x86, 0x71, 0xA2, 0xA0, 0xD9, 0xA3, 0x43, 0x1C, 0x4C, 0x8B, 0xA2, 0x1A, 0xCF, 0x1A,
|
|
||||||
0x4E, 0x7A, 0x1D, 0x41, 0x5C, 0x0E, 0x71, 0x91, 0xA0, 0x5E, 0xB3, 0xEB, 0xB5, 0x84, 0xA0, 0x02,
|
|
||||||
0x16, 0xA2, 0x8E, 0x87, 0x9D, 0x34, 0xD4, 0x1C, 0xEC, 0xA2, 0xC8, 0x63, 0x05, 0xED, 0x50, 0x95,
|
|
||||||
0xFF, 0xC6, 0xC2, 0xD7, 0x7F, 0xF2, 0x36, 0xDE, 0x12, 0xBE, 0xFC, 0x6B, 0x9A, 0x26, 0x08, 0x1A,
|
|
||||||
0x0C, 0x30, 0x82, 0x73, 0x36, 0x96, 0xAD, 0x66, 0xB1, 0xB8, 0x89, 0xB0, 0x58, 0xD2, 0x60, 0xE6,
|
|
||||||
0xDC, 0x93, 0xA6, 0xFF, 0xE2, 0x5C, 0xA6, 0x4B, 0xED, 0x28, 0x9C, 0x05, 0xF9, 0x12, 0x0A, 0x33,
|
|
||||||
0x55, 0x27, 0xF4, 0x88, 0x70, 0x63, 0xE4, 0xFB, 0xDC, 0xB6, 0x32, 0x0B, 0x60, 0xE2, 0xE9, 0x12,
|
|
||||||
0xA5, 0x16, 0xF1, 0xC9, 0xAB, 0x98, 0xB4, 0xEB, 0x22, 0x28, 0xD5, 0x0C, 0x6B, 0x25, 0xA4, 0x30,
|
|
||||||
0x8F, 0x92, 0x90, 0x3D, 0x40, 0x1F, 0xD6, 0x8B, 0xFA, 0x9D, 0x69, 0xC2, 0x5E, 0x83, 0xDC, 0x90,
|
|
||||||
0x02, 0x82, 0x6E, 0x07, 0x69, 0x55, 0xA3, 0x6A, 0x9C, 0xC0, 0x1F, 0xBD, 0xE0, 0x30, 0xA9, 0x72,
|
|
||||||
0xBD, 0xBE, 0xD0, 0x7D, 0x9F, 0xCC, 0xF7, 0xEB, 0x24, 0x80, 0xE6, 0xAC, 0x59, 0x85, 0x4F, 0xA1,
|
|
||||||
0x71, 0xD7, 0x2A, 0x3C, 0xE0, 0x57, 0x38, 0x7C, 0x9D, 0x53, 0x17, 0xFD, 0xB5, 0xD4, 0x11, 0x7D,
|
|
||||||
0xFA, 0xA5, 0x2C, 0xF3, 0xEF, 0x60, 0x58, 0xE4, 0x54, 0xD8, 0x37, 0x0E, 0xCB, 0xF5, 0x09, 0xB7,
|
|
||||||
0xF4, 0x45, 0x55, 0x49, 0xED, 0x2E, 0xCB, 0x6A, 0x02, 0x62, 0x7C, 0x68, 0x21, 0x01, 0xB4, 0x92,
|
|
||||||
0xE6, 0xC2, 0x99, 0x55, 0x73, 0xBB, 0xC4, 0xF3, 0xCA, 0x1E, 0x1D, 0xCD, 0x55, 0x8F, 0x82, 0x9F,
|
|
||||||
0xE7, 0xFD, 0x3A, 0xEF, 0xFE, 0x7B, 0x65, 0x47, 0x10, 0x73, 0xDF, 0x40, 0xF6, 0xFE, 0x93, 0x68,
|
|
||||||
0x06, 0xCA, 0x3D, 0x49, 0xB2, 0xCE, 0xA3, 0x0F, 0x60, 0x5D, 0x74, 0x98, 0xAC, 0x91, 0x71, 0x25,
|
|
||||||
0x1C, 0x11, 0x58, 0x89, 0xCD, 0x35, 0xA3, 0x01, 0x0D, 0x89, 0x58, 0xE6, 0x05, 0xD8, 0x43, 0xBC,
|
|
||||||
0xC8, 0x2F, 0xB6, 0xE1, 0xB9, 0xE6, 0x91, 0xBB, 0x94, 0xCA, 0x94, 0x6D, 0xF4, 0x61, 0x4B, 0x87,
|
|
||||||
0x8A, 0xAC, 0x00, 0x49, 0xBC, 0x0A, 0xE7, 0x15, 0x8A, 0x7B, 0xC1, 0xB7, 0xF5, 0x7B, 0x63, 0x38,
|
|
||||||
0x09, 0xDC, 0x6E, 0x80, 0x27, 0xA9, 0x58, 0x23, 0xF9, 0x34, 0xE5, 0x4A, 0x6F, 0x79, 0x8F, 0x16,
|
|
||||||
0x71, 0x2D, 0xAD, 0xAE, 0x34, 0xC2, 0x78, 0x8E, 0x65, 0xD1, 0x23, 0xE9, 0x02, 0x4B, 0x55, 0x17,
|
|
||||||
0xA0, 0xCF, 0x92, 0x4D, 0xB8, 0x26, 0xC9, 0x41, 0x3E, 0xF4, 0xB0, 0xCB, 0xC4, 0xC2, 0x9B, 0x57,
|
|
||||||
0xC7, 0x93, 0x42, 0x84, 0x94, 0x67, 0xDD, 0x5B, 0xE2, 0x99, 0xAD, 0x9F, 0x52, 0xDF, 0x2C, 0xA3,
|
|
||||||
0xE5, 0x31, 0xB5, 0x9C, 0x3C, 0x55, 0x3C, 0x2D, 0xB1, 0xC2, 0x3C, 0x38, 0xD3, 0x97, 0x09, 0x0C,
|
|
||||||
0x46, 0xE0, 0x3F, 0xB4, 0xFA, 0x29, 0x5F, 0x3F, 0xAF, 0xBE, 0x14, 0x27, 0xCB, 0x9E, 0x85, 0x94,
|
|
||||||
0x48, 0x5B, 0x6C, 0x2E, 0x0A, 0x1A, 0x73, 0x98, 0xCD, 0x70, 0x5F, 0x58, 0x79, 0xC0, 0x6A, 0xAB,
|
|
||||||
0x8F, 0xA0, 0x58, 0x72, 0x17, 0xC2, 0x6D, 0x26, 0xD8, 0xB6, 0xE8, 0xDE, 0xD9, 0xF2, 0xAC, 0x76,
|
|
||||||
0xCA, 0x6F, 0xF6, 0x2A, 0xB6, 0x47, 0xC3, 0x1C, 0x0E, 0xA8, 0x03, 0x9A, 0x44, 0x0C, 0x37, 0xE5,
|
|
||||||
0x92, 0xEE, 0x49, 0xE2, 0xD4, 0x27, 0xCB, 0xD3, 0x2E, 0x87, 0x41, 0x1E, 0x9A, 0xA2, 0x66, 0x35,
|
|
||||||
0x7E, 0xAF, 0x93, 0x5F, 0x45, 0x31, 0x3C, 0x86, 0xFE, 0xC6, 0xEF, 0x5B, 0x4C, 0x1B, 0x8B, 0x30,
|
|
||||||
0xCB, 0xA7, 0x41, 0x6D, 0x71, 0x09, 0x16, 0x57, 0x7A, 0xC4, 0x71, 0xB0, 0x5F, 0xB8, 0x39, 0x8E,
|
|
||||||
0x67, 0x77, 0xFC, 0xC7, 0xC9, 0x2D, 0xBF, 0x3C, 0x98, 0x3D, 0x9D, 0x38, 0xE7, 0xCF, 0x00, 0xF2,
|
|
||||||
0x4F, 0x06, 0xE4, 0x92, 0x5F, 0xB1, 0x3D, 0x14, 0x86, 0x2D, 0x95, 0xDF, 0x8B, 0xE7, 0x1E, 0x2E,
|
|
||||||
0x08, 0x12, 0x87, 0x0C, 0x15, 0xE2, 0xB4, 0x54, 0x8F, 0x76, 0xE9, 0xDC, 0x35, 0x71, 0x5D, 0x2C,
|
|
||||||
0x86, 0x15, 0x40, 0xB5, 0xA5, 0x16, 0x96, 0xE5, 0xAA, 0xE0, 0x9A, 0x9D, 0x52, 0xAD, 0xC7, 0x8F,
|
|
||||||
0x9E, 0x3D, 0x7D, 0x7A, 0xDA, 0x7C, 0xEC, 0x77, 0xC2, 0x41, 0xF2, 0xF7, 0x57, 0x71, 0x09, 0x16,
|
|
||||||
0xBD, 0x8C, 0xC1, 0x42, 0x34, 0x3C, 0x3F, 0x16, 0xD2, 0xE6, 0x34, 0x38, 0x06, 0x15, 0x56, 0x28,
|
|
||||||
0x95, 0xE4, 0xC6, 0x32, 0xBD, 0x52, 0x92, 0x10, 0x82, 0xB4, 0x83, 0x82, 0x25, 0x24, 0x82, 0x4C,
|
|
||||||
0xC4, 0xB4, 0x22, 0x4A, 0x9A, 0x2A, 0x22, 0xBB, 0x43, 0xC7, 0xF3, 0xAA, 0x0B, 0x6B, 0x92, 0xB0,
|
|
||||||
0x4F, 0xA8, 0xB0, 0xB3, 0x4A, 0x20, 0xB0, 0x09, 0x76, 0x7E, 0x33, 0xB2, 0x82, 0x26, 0xD3, 0x2F,
|
|
||||||
0x71, 0x7B, 0x6E, 0xFD, 0x2F, 0xA7, 0x76, 0x03, 0xD4, 0xC7, 0x3C, 0xDA, 0x93, 0x93, 0xAB, 0xC5,
|
|
||||||
0xCC, 0x43, 0x90, 0x71, 0xAA, 0xD6, 0x7B, 0x2C, 0x02, 0x17, 0xE0, 0x5D, 0xEA, 0xD6, 0x05, 0x29,
|
|
||||||
0x32, 0x05, 0x8B, 0xF3, 0xAB, 0xA9, 0x8A, 0xC9, 0x8A, 0xBA, 0x8C, 0x44, 0xBC, 0xAC, 0x51, 0x48,
|
|
||||||
0x88, 0xA3, 0x03, 0x11, 0x59, 0x43, 0xE4, 0x45, 0xE0, 0xDA, 0x5A, 0x55, 0xB5, 0xFE, 0xF3, 0xC7,
|
|
||||||
0x8B, 0x4B, 0x0D, 0x92, 0xAC, 0x3A, 0xAE, 0xD5, 0xAB, 0x55, 0xFD, 0xFC, 0x58, 0x92, 0x6C, 0x2C,
|
|
||||||
0xEB, 0x99, 0x6A, 0xDD, 0x0A, 0x51, 0xF5, 0x33, 0x10, 0x55, 0xAD, 0x37, 0xB6, 0x17, 0x75, 0xA6,
|
|
||||||
0x5A, 0x42, 0x12, 0x08, 0x19, 0x3F, 0x3D, 0x3D, 0xDB, 0x5E, 0xD0, 0x53, 0xD0, 0xE9, 0x37, 0x90,
|
|
||||||
0x74, 0x06, 0xD6, 0x9D, 0xEE, 0x62, 0xDC, 0xA9, 0x6A, 0x71, 0x39, 0xA7, 0x8D, 0xEA, 0xB8, 0x71,
|
|
||||||
0xB6, 0x83, 0x9C, 0x27, 0x6A, 0x72, 0x2B, 0xC9, 0x43, 0x36, 0x1D, 0xA9, 0x56, 0xFB, 0xE7, 0xE7,
|
|
||||||
0x5A, 0x03, 0x74, 0xAC, 0x3F, 0x3B, 0xDD, 0x5E, 0x76, 0x43, 0xB5, 0x7E, 0xE1, 0x4A, 0x9E, 0xD4,
|
|
||||||
0x41, 0x50, 0x63, 0x07, 0x25, 0x4F, 0x54, 0xEB, 0xA5, 0x90, 0x04, 0x52, 0xC6, 0xB5, 0xA7, 0x3B,
|
|
||||||
0xA8, 0x04, 0xE1, 0xF5, 0x8B, 0x90, 0x04, 0xF1, 0xC5, 0xC3, 0xEB, 0x81, 0x92, 0xA0, 0x50, 0x0A,
|
|
||||||
0xD7, 0xDC, 0x93, 0xA7, 0x8B, 0xD5, 0xA7, 0x70, 0xF9, 0xBE, 0x34, 0xFE, 0x1C, 0x41, 0x4D, 0x67,
|
|
||||||
0x93, 0x8D, 0x93, 0x38, 0xE1, 0x03, 0x93, 0xE4, 0xE0, 0x61, 0xF9, 0x9B, 0xD3, 0x24, 0x7B, 0x4A,
|
|
||||||
0xA0, 0x5A, 0xB5, 0xEA, 0x1A, 0x0B, 0x04, 0x6F, 0xBE, 0x0A, 0x0A, 0xE6, 0x82, 0x01, 0xAA, 0x02,
|
|
||||||
0xA2, 0x44, 0x0E, 0x2B, 0x7D, 0x34, 0x86, 0x18, 0x3D, 0x51, 0x73, 0x79, 0xBD, 0x55, 0x89, 0x58,
|
|
||||||
0xA2, 0x2D, 0x1A, 0xAB, 0xD6, 0xE9, 0xC9, 0x3A, 0x7F, 0xEF, 0x00, 0x47, 0x47, 0x74, 0x70, 0x1F,
|
|
||||||
0x87, 0xE1, 0xC6, 0x88, 0xCC, 0x58, 0x55, 0xEB, 0x2A, 0x1B, 0xEF, 0x82, 0x4B, 0xB9, 0xBE, 0x03,
|
|
||||||
0x2E, 0x39, 0x75, 0x24, 0x34, 0xE5, 0x7A, 0x02, 0x4D, 0x5D, 0x9D, 0x65, 0xC4, 0xD7, 0x04, 0x66,
|
|
||||||
0x9D, 0xB6, 0xBB, 0xE0, 0xC2, 0x9B, 0x78, 0x80, 0x42, 0xB6, 0x31, 0x2A, 0x29, 0x23, 0x94, 0xB5,
|
|
||||||
0x64, 0x74, 0x30, 0x44, 0x32, 0x55, 0xFE, 0x01, 0x78, 0x84, 0x88, 0x45, 0x81, 0x78, 0xFA, 0xBE,
|
|
||||||
0x31, 0x22, 0x33, 0x56, 0xE8, 0x87, 0xD9, 0xF8, 0x60, 0xA8, 0xE4, 0xD4, 0xF9, 0x27, 0xE0, 0x32,
|
|
||||||
0xC0, 0x36, 0x41, 0xDE, 0x07, 0xEC, 0xBA, 0xD0, 0xB2, 0x36, 0xC7, 0xA6, 0xC0, 0x0E, 0xF8, 0xC8,
|
|
||||||
0x63, 0xE5, 0x46, 0x1C, 0x6F, 0xBC, 0x46, 0x9C, 0x13, 0xF7, 0xB5, 0x16, 0x8A, 0xD5, 0xE5, 0xEB,
|
|
||||||
0x96, 0x37, 0x34, 0xD3, 0x73, 0xCB, 0x15, 0x42, 0x0D, 0x84, 0xE0, 0xAE, 0xB8, 0xE7, 0xDB, 0x5A,
|
|
||||||
0x46, 0x5D, 0xB5, 0x5E, 0x04, 0x68, 0x22, 0xBE, 0x86, 0xDD, 0x65, 0xD1, 0xF3, 0x1E, 0x3B, 0xCA,
|
|
||||||
0xAF, 0x70, 0x23, 0xB7, 0xCB, 0x0A, 0xEC, 0x45, 0x80, 0xB1, 0xBF, 0x9B, 0x94, 0x27, 0xD0, 0xCC,
|
|
||||||
0x60, 0xB0, 0x9B, 0x10, 0x58, 0xB0, 0xDE, 0xE2, 0x01, 0x41, 0xDF, 0xC3, 0x82, 0x0B, 0x8D, 0x3A,
|
|
||||||
0x1B, 0xA7, 0x05, 0xF0, 0xA8, 0xD6, 0xE5, 0xEF, 0x57, 0x1B, 0x17, 0x29, 0xF9, 0xF0, 0xE9, 0x21,
|
|
||||||
0x11, 0x2E, 0xAB, 0x53, 0xA2, 0xA0, 0xBA, 0x70, 0xB3, 0xB9, 0x3C, 0x73, 0x1E, 0x7A, 0xC3, 0xB9,
|
|
||||||
0xC4, 0xAE, 0x54, 0x41, 0xF1, 0x7C, 0x46, 0xCD, 0x99, 0xF9, 0x30, 0x1B, 0xBF, 0x5D, 0x05, 0x03,
|
|
||||||
0x25, 0x3E, 0x74, 0x11, 0xD9, 0xBC, 0xAF, 0xA4, 0x8C, 0x02, 0x29, 0xE5, 0x05, 0x8C, 0xF6, 0x05,
|
|
||||||
0x97, 0x9C, 0xF6, 0x60, 0x98, 0x25, 0x56, 0x1F, 0x1A, 0x38, 0x50, 0xA4, 0x4F, 0x9D, 0xCD, 0x1F,
|
|
||||||
0x47, 0x24, 0x7C, 0xAA, 0x05, 0xA8, 0xBD, 0x86, 0xC1, 0xC6, 0x5D, 0x26, 0x15, 0xF0, 0x8D, 0xDB,
|
|
||||||
0xCB, 0x65, 0xC4, 0xE8, 0x2E, 0x9D, 0xE5, 0x36, 0xF2, 0xFD, 0xC9, 0x2E, 0x6D, 0xA5, 0xED, 0xD1,
|
|
||||||
0xC8, 0xD9, 0x5E, 0x02, 0xF4, 0x94, 0xB7, 0xAE, 0x4B, 0xEC, 0xED, 0xBB, 0x12, 0x74, 0x94, 0x97,
|
|
||||||
0xB4, 0xFF, 0x40, 0xFE, 0x6F, 0x5C, 0xC5, 0xB1, 0xBD, 0x79, 0x81, 0xC0, 0x36, 0xA0, 0x78, 0xD3,
|
|
||||||
0x56, 0x6E, 0x6F, 0xDE, 0xDC, 0xBE, 0x7D, 0xBF, 0x9F, 0xEA, 0x00, 0x73, 0x1E, 0xA8, 0x30, 0x70,
|
|
||||||
0x6B, 0x0F, 0x5D, 0x13, 0x40, 0x89, 0xFA, 0x36, 0x38, 0xD5, 0x25, 0x50, 0xD7, 0xB7, 0xEF, 0xF6,
|
|
||||||
0x85, 0x52, 0xFD, 0x70, 0x30, 0xD5, 0xBF, 0x07, 0x9C, 0x3E, 0x78, 0x78, 0x88, 0xBD, 0x2D, 0xB0,
|
|
||||||
0x92, 0x8C, 0x1C, 0x2F, 0xE5, 0x15, 0x1F, 0x1D, 0xEC, 0x46, 0x2E, 0x53, 0xE5, 0x1F, 0x70, 0x1B,
|
|
||||||
0x07, 0x51, 0xF1, 0x41, 0x28, 0xBD, 0x4D, 0xF2, 0x48, 0x4E, 0xD5, 0xBA, 0x19, 0x0F, 0x68, 0x18,
|
|
||||||
0x05, 0x0F, 0x6C, 0xA8, 0xCB, 0x11, 0xD9, 0xE5, 0xC9, 0xE0, 0x4C, 0x15, 0x89, 0x48, 0xFA, 0x68,
|
|
||||||
0x90, 0x3F, 0xD9, 0xCF, 0x30, 0xA9, 0x57, 0x1B, 0x5F, 0x15, 0x15, 0x2E, 0xFC, 0x5B, 0x02, 0xD3,
|
|
||||||
0xDD, 0xA2, 0xEF, 0x74, 0x79, 0xDF, 0x79, 0xD1, 0xDE, 0x4F, 0x29, 0xEB, 0x1E, 0xAC, 0xE1, 0x74,
|
|
||||||
0x0F, 0xDA, 0x70, 0x14, 0xF9, 0x6D, 0x67, 0x06, 0xD3, 0x96, 0x37, 0x11, 0x09, 0x23, 0xDC, 0x3B,
|
|
||||||
0x6F, 0x73, 0x03, 0x91, 0x7F, 0xA8, 0x3E, 0xDE, 0x25, 0x75, 0x52, 0x35, 0x8A, 0x99, 0x73, 0x32,
|
|
||||||
0xCB, 0x9B, 0x27, 0x5F, 0x35, 0x6B, 0x4E, 0xD6, 0x6A, 0xBB, 0x4B, 0xD2, 0x70, 0x4B, 0x6C, 0x4C,
|
|
||||||
0x3C, 0xFE, 0xD2, 0xE3, 0xA6, 0x80, 0xE4, 0x78, 0x25, 0x26, 0x4A, 0x5B, 0x1E, 0xED, 0x82, 0x4D,
|
|
||||||
0x7D, 0x17, 0x6C, 0xF2, 0x1A, 0x15, 0xE1, 0x39, 0xFD, 0x46, 0x9D, 0xA6, 0x56, 0x3F, 0xFB, 0x96,
|
|
||||||
0xF0, 0x74, 0x06, 0x9B, 0xD7, 0x34, 0xE0, 0x51, 0xAD, 0xAB, 0x77, 0xFB, 0xA9, 0x69, 0x7C, 0xB2,
|
|
||||||
0x07, 0xD6, 0xB4, 0x9D, 0x2A, 0x98, 0x30, 0xEA, 0xD0, 0x4B, 0xB1, 0xD1, 0x16, 0x68, 0x8C, 0xB8,
|
|
||||||
0xE2, 0xBF, 0xEF, 0x09, 0x8D, 0xD1, 0xC3, 0xD1, 0xF8, 0xCA, 0x1D, 0x66, 0xF4, 0x3D, 0xE0, 0x13,
|
|
||||||
0xA0, 0xD1, 0x87, 0x6E, 0x1F, 0x6D, 0x8C, 0x51, 0xC2, 0xA7, 0x5A, 0xEF, 0xD1, 0x48, 0x79, 0xF1,
|
|
||||||
0xFA, 0x72, 0x2F, 0x58, 0xA5, 0x93, 0x1E, 0x06, 0xAF, 0xCC, 0xE4, 0x43, 0x63, 0xE6, 0x61, 0x7F,
|
|
||||||
0xF3, 0xA4, 0xE2, 0x4C, 0xAA, 0xF5, 0x0A, 0xFB, 0xA1, 0xD2, 0xA6, 0x41, 0xB2, 0xED, 0x68, 0x2F,
|
|
||||||
0xA8, 0x89, 0x99, 0x0F, 0x03, 0x99, 0x34, 0xFA, 0xD0, 0x78, 0xF5, 0xFA, 0x24, 0x08, 0x68, 0xB0,
|
|
||||||
0x31, 0x64, 0x09, 0x9F, 0x6A, 0xBD, 0x2C, 0xBF, 0x16, 0xA3, 0xBD, 0xC0, 0x95, 0xCE, 0x7A, 0x18,
|
|
||||||
0xC4, 0x32, 0x9B, 0x0F, 0x0D, 0xDA, 0xD0, 0xF5, 0xC8, 0x60, 0x63, 0xC8, 0x04, 0x97, 0x6A, 0xFD,
|
|
||||||
0x56, 0x7E, 0x0E, 0x9F, 0x7B, 0x81, 0x4B, 0xCE, 0x78, 0x18, 0xB0, 0x12, 0x6B, 0x0F, 0x0D, 0x95,
|
|
||||||
0x63, 0x8F, 0x36, 0x06, 0x0A, 0x78, 0x54, 0xEB, 0xBA, 0xFD, 0xBB, 0xA2, 0x5D, 0xD3, 0x91, 0xCF,
|
|
||||||
0x5F, 0xFC, 0x53, 0x6E, 0xDE, 0xE8, 0x7B, 0x41, 0x8C, 0x4F, 0x7D, 0x18, 0xBC, 0x84, 0xD1, 0x87,
|
|
||||||
0x46, 0x4B, 0xBC, 0x04, 0xDC, 0x41, 0x9B, 0x97, 0xC3, 0x94, 0x91, 0xBF, 0xFB, 0x02, 0x23, 0xE5,
|
|
||||||
0x0A, 0xED, 0xA7, 0x20, 0x66, 0xF3, 0xEE, 0x63, 0xD1, 0x3E, 0x33, 0xF2, 0xD0, 0x38, 0xB9, 0xC8,
|
|
||||||
0xC6, 0x1F, 0x1C, 0xCC, 0xB6, 0x79, 0xF1, 0x22, 0xC7, 0xAB, 0x5A, 0xCF, 0xE1, 0x40, 0xB9, 0x16,
|
|
||||||
0x07, 0xFB, 0x5A, 0x72, 0xE4, 0xE7, 0xDF, 0x07, 0x6A, 0x05, 0x7B, 0xBF, 0x0B, 0xE0, 0x60, 0x81,
|
|
||||||
0x47, 0xBB, 0xFE, 0x56, 0xEF, 0x53, 0x17, 0xD8, 0x13, 0xF8, 0xDE, 0xCB, 0xE3, 0xFD, 0x02, 0x38,
|
|
||||||
0x53, 0x62, 0x6F, 0x18, 0xE6, 0xEC, 0xDE, 0x07, 0x8C, 0xE9, 0x66, 0x04, 0xF1, 0x58, 0x40, 0xEE,
|
|
||||||
0x41, 0x5E, 0x87, 0x94, 0x24, 0x93, 0x8F, 0x6E, 0x30, 0x2B, 0x87, 0x8C, 0x78, 0x9E, 0x6A, 0xBD,
|
|
||||||
0xC0, 0x4C, 0xB9, 0xE5, 0xC3, 0xF3, 0x63, 0x49, 0xF0, 0x70, 0x29, 0xC9, 0x0B, 0xFF, 0x7C, 0xDF,
|
|
||||||
0x38, 0xEA, 0xAB, 0xD6, 0x2D, 0xDF, 0x44, 0x0D, 0xB2, 0xF8, 0xD1, 0xE6, 0xC2, 0x84, 0x13, 0xB1,
|
|
||||||
0x1F, 0x50, 0x50, 0x2A, 0x03, 0x29, 0xD9, 0xAA, 0xAA, 0x2A, 0xE9, 0x28, 0x77, 0xCE, 0xBA, 0x11,
|
|
||||||
0xC4, 0x0A, 0x8F, 0xB2, 0xF5, 0xD3, 0xF1, 0x6F, 0x61, 0xED, 0xD5, 0x5F, 0xD6, 0x9E, 0x1F, 0xFB,
|
|
||||||
0x68, 0x89, 0xBB, 0x57, 0xA0, 0x70, 0x2E, 0x77, 0xB1, 0xAF, 0x10, 0x95, 0x6D, 0xA6, 0x10, 0x9E,
|
|
||||||
0x98, 0xED, 0xA7, 0xC9, 0xCC, 0x9A, 0xDB, 0x67, 0x93, 0x3E, 0xB0, 0x7D, 0x58, 0xD2, 0x8A, 0x1D,
|
|
||||||
0x37, 0x49, 0x3F, 0xE4, 0xC3, 0xCC, 0xFD, 0xFF, 0xFB, 0xEF, 0xBA, 0x98, 0x21, 0xFD, 0x6E, 0x4E,
|
|
||||||
0x31, 0x55, 0x09, 0x03, 0xBB, 0xA5, 0xAE, 0xDA, 0x9A, 0xB1, 0xC2, 0xF2, 0xE3, 0x65, 0xA6, 0xCF,
|
|
||||||
0x11, 0x2F, 0xF1, 0xF5, 0x79, 0x68, 0x07, 0x64, 0xC0, 0xAC, 0x7F, 0x39, 0xD4, 0x8E, 0xFA, 0xD8,
|
|
||||||
0x67, 0x15, 0xE4, 0x38, 0x37, 0x43, 0x18, 0xBC, 0x22, 0x21, 0xC3, 0xE0, 0x05, 0xAD, 0x74, 0xFD,
|
|
||||||
0xF6, 0x75, 0x5B, 0x6E, 0x51, 0x79, 0x45, 0x91, 0x83, 0x9D, 0x92, 0xE1, 0x46, 0xBE, 0x90, 0xA3,
|
|
||||||
0xE9, 0xD3, 0x74, 0xA8, 0x74, 0xB4, 0x2B, 0x7D, 0xEA, 0x41, 0xD0, 0xB6, 0x9B, 0xB2, 0x3C, 0x68,
|
|
||||||
0x57, 0x15, 0x9E, 0xE3, 0xFA, 0xD4, 0x46, 0x21, 0x2E, 0xA5, 0x89, 0x5E, 0x32, 0xDB, 0xAD, 0xAB,
|
|
||||||
0x4A, 0xB2, 0xF6, 0xB9, 0xA8, 0xF1, 0x0D, 0x4F, 0x60, 0xF4, 0x5D, 0x53, 0x10, 0x89, 0x47, 0x8A,
|
|
||||||
0x25, 0x53, 0x8C, 0xE5, 0x97, 0xF3, 0x65, 0xEA, 0x63, 0xC9, 0x22, 0x1E, 0x5C, 0xE6, 0x89, 0x65,
|
|
||||||
0x64, 0xA5, 0xD4, 0x51, 0xA7, 0x4F, 0x18, 0xA7, 0x2C, 0xD5, 0x4A, 0x09, 0x55, 0x52, 0x4A, 0xCC,
|
|
||||||
0x00, 0xB3, 0x28, 0xF0, 0x9B, 0x31, 0x00, 0x1B, 0x32, 0xE5, 0xBA, 0xF5, 0xF1, 0x87, 0xA9, 0x1D,
|
|
||||||
0x1F, 0x8B, 0x97, 0x5D, 0xA9, 0x77, 0x31, 0x44, 0x41, 0xEB, 0x87, 0xE9, 0x55, 0x85, 0x38, 0xF1,
|
|
||||||
0x63, 0x98, 0x03, 0xC6, 0xED, 0xF8, 0x63, 0xD3, 0xE5, 0xFF, 0x71, 0x41, 0xBB, 0xD6, 0x2B, 0xAC,
|
|
||||||
0x87, 0x7D, 0xED, 0xA6, 0x65, 0x4D, 0x39, 0x37, 0xF5, 0x70, 0xC5, 0xA3, 0x5D, 0xED, 0x63, 0x80,
|
|
||||||
0x3F, 0x47, 0x18, 0x84, 0x31, 0xAA, 0xFC, 0x30, 0xBD, 0x8E, 0x15, 0x97, 0xF8, 0x24, 0xEC, 0x61,
|
|
||||||
0xC7, 0x50, 0x42, 0x86, 0x58, 0x14, 0x9A, 0x70, 0xFA, 0xA6, 0x22, 0xC7, 0xF1, 0x47, 0x3D, 0xD6,
|
|
||||||
0x63, 0x98, 0x46, 0xB1, 0x5B, 0x99, 0x97, 0x3D, 0x6A, 0x8B, 0x57, 0x3A, 0x2B, 0x34, 0x20, 0x5D,
|
|
||||||
0xE2, 0x37, 0xA5, 0x6E, 0xB8, 0x75, 0x05, 0x33, 0x81, 0x7B, 0x78, 0x48, 0x71, 0x00, 0x38, 0x1A,
|
|
||||||
0x5A, 0x49, 0xC6, 0x61, 0x49, 0x8F, 0x0D, 0x77, 0x81, 0x20, 0xC0, 0x7D, 0x3A, 0xC4, 0x79, 0x9A,
|
|
||||||
0xEE, 0x72, 0x21, 0x69, 0x7E, 0x96, 0x74, 0xE3, 0x2A, 0xDB, 0x6B, 0xDE, 0x3A, 0xAA, 0xC6, 0x46,
|
|
||||||
0x6F, 0xA5, 0xD0, 0x15, 0x3C, 0xB5, 0xD8, 0x20, 0x2D, 0xED, 0xCA, 0x68, 0x1B, 0xD7, 0x3A, 0x70,
|
|
||||||
0x5E, 0xB7, 0x8E, 0x34, 0x3F, 0xF2, 0xBC, 0xA3, 0xD6, 0xB5, 0xFE, 0xF7, 0xDF, 0xD7, 0x4D, 0x1E,
|
|
||||||
0x04, 0x37, 0xCD, 0x19, 0xE2, 0xAD, 0x56, 0x4B, 0x86, 0xC2, 0x05, 0x38, 0x32, 0xC3, 0xDE, 0x68,
|
|
||||||
0xB7, 0x8E, 0x8E, 0xDA, 0x46, 0x76, 0xDC, 0x6A, 0xEB, 0xA6, 0xB8, 0x2E, 0x80, 0x36, 0x92, 0x4F,
|
|
||||||
0x38, 0x6B, 0x5C, 0x3F, 0x7E, 0x7C, 0x73, 0xD4, 0x6A, 0xB5, 0x2F, 0x78, 0x88, 0x99, 0x47, 0x70,
|
|
||||||
0xA8, 0x95, 0x10, 0xB6, 0xA5, 0x5C, 0xE2, 0x5C, 0xB4, 0x2F, 0xB0, 0x36, 0xD4, 0x4D, 0x97, 0xFF,
|
|
||||||
0x29, 0xA1, 0x6E, 0xFE, 0x82, 0xE6, 0x6A, 0x4C, 0x37, 0xB0, 0x16, 0xEA, 0x20, 0x1C, 0xF3, 0xB1,
|
|
||||||
0x2B, 0xC6, 0xA5, 0xF4, 0xAD, 0xA4, 0x1C, 0xAD, 0xAB, 0x8D, 0x75, 0x13, 0xF3, 0x3F, 0xA5, 0x62,
|
|
||||||
0xE3, 0x48, 0x69, 0x60, 0xDE, 0xF6, 0x45, 0x4F, 0xF3, 0x75, 0xB3, 0x0B, 0x7F, 0x74, 0x3D, 0x6E,
|
|
||||||
0x66, 0x70, 0x42, 0x34, 0x04, 0x93, 0x5B, 0x11, 0xB1, 0x34, 0xB8, 0xF4, 0x3C, 0xAD, 0x24, 0x77,
|
|
||||||
0xE0, 0x95, 0xF4, 0x0A, 0x74, 0xA2, 0x1B, 0xC4, 0xB3, 0x41, 0xF8, 0x98, 0xFA, 0xB6, 0x47, 0xEC,
|
|
||||||
0xBB, 0x96, 0xC6, 0x1D, 0x87, 0x21, 0x45, 0xE4, 0xDE, 0xE0, 0x37, 0xD4, 0xC1, 0x7A, 0x1C, 0x83,
|
|
||||||
0x7A, 0x22, 0xEE, 0x64, 0x84, 0xCA, 0xF0, 0xF9, 0x98, 0xC4, 0x60, 0x96, 0x73, 0x90, 0x66, 0x32,
|
|
||||||
0xA2, 0x95, 0xAB, 0xCA, 0xA7, 0x90, 0x27, 0x61, 0xBC, 0x84, 0xE4, 0x3E, 0xD5, 0x8A, 0x3D, 0x36,
|
|
||||||
0xA7, 0x63, 0x1B, 0x94, 0x22, 0x1A, 0x80, 0xF2, 0x67, 0x1B, 0xEC, 0xFD, 0xCB, 0x38, 0xAA, 0xF1,
|
|
||||||
0xD0, 0xD5, 0x93, 0xE8, 0xFC, 0x34, 0x0B, 0x5F, 0xE8, 0x53, 0x37, 0x1E, 0xE6, 0xC3, 0xAB, 0xC9,
|
|
||||||
0xCF, 0x10, 0x5C, 0xB2, 0x72, 0x41, 0x98, 0xDC, 0xAD, 0xA3, 0x99, 0x95, 0x57, 0xA0, 0xF6, 0x56,
|
|
||||||
0x53, 0x67, 0x9D, 0x10, 0xC8, 0xFA, 0xAB, 0xC9, 0x0A, 0xAD, 0x0E, 0x48, 0xFD, 0xD5, 0xA4, 0xB9,
|
|
||||||
0x46, 0x06, 0x84, 0x74, 0x35, 0x61, 0xBE, 0x7C, 0x03, 0xE5, 0x40, 0x82, 0x35, 0x22, 0xBE, 0x43,
|
|
||||||
0x47, 0x90, 0xD3, 0x74, 0xA0, 0x81, 0x4A, 0x15, 0xE2, 0x83, 0x0D, 0x2F, 0x7F, 0x7D, 0xFD, 0xAA,
|
|
||||||
0x55, 0xCA, 0x37, 0xD8, 0x52, 0x6C, 0x7C, 0x96, 0x0C, 0x9F, 0x2A, 0xBC, 0x8E, 0x73, 0x28, 0x7F,
|
|
||||||
0x2A, 0x99, 0x67, 0xB5, 0x12, 0x07, 0x94, 0x53, 0x7C, 0x84, 0x18, 0xBC, 0x5B, 0x90, 0x40, 0x07,
|
|
||||||
0x99, 0x80, 0xA6, 0x57, 0x0C, 0x13, 0x3E, 0xDF, 0x4C, 0x18, 0x54, 0x2E, 0x34, 0x00, 0xF8, 0xF1,
|
|
||||||
0xC5, 0x07, 0xBB, 0x03, 0xD5, 0xEA, 0x1A, 0x31, 0x5C, 0xF1, 0xE9, 0x08, 0xC2, 0x40, 0x4A, 0x8E,
|
|
||||||
0x0D, 0xBA, 0xC8, 0x8F, 0xC5, 0x85, 0x7E, 0xF1, 0x82, 0x84, 0xF5, 0xAA, 0x38, 0x3D, 0x04, 0x7B,
|
|
||||||
0x4E, 0xB5, 0xE6, 0xD5, 0x05, 0xB0, 0x9B, 0x9F, 0x41, 0xBA, 0xE1, 0x17, 0xB9, 0x3B, 0x90, 0x04,
|
|
||||||
0xB1, 0xB1, 0x55, 0x9C, 0x65, 0xB9, 0xD0, 0xE3, 0x05, 0x5F, 0x88, 0xE3, 0xB9, 0x9D, 0x45, 0x5A,
|
|
||||||
0xB0, 0x1A, 0x1C, 0x9E, 0xDF, 0xBA, 0x11, 0xDE, 0x4B, 0x90, 0xFB, 0x66, 0x15, 0x68, 0xD9, 0x3D,
|
|
||||||
0x41, 0x36, 0xFF, 0xBD, 0x5F, 0x49, 0x6F, 0x06, 0x45, 0xBD, 0xC0, 0xCC, 0x40, 0x37, 0x82, 0xAC,
|
|
||||||
0x63, 0xAD, 0xA8, 0x28, 0x71, 0xA2, 0x79, 0x74, 0x8F, 0x62, 0x98, 0x6B, 0x3E, 0xBC, 0x97, 0x20,
|
|
||||||
0xFF, 0x4E, 0x05, 0xE8, 0x12, 0x2D, 0xE8, 0x12, 0xE9, 0x46, 0x94, 0xE9, 0x92, 0x95, 0xBD, 0x74,
|
|
||||||
0xF6, 0xD1, 0x3D, 0xC2, 0xD3, 0x82, 0xA7, 0x1B, 0xE3, 0xD5, 0x54, 0x85, 0x57, 0x24, 0x41, 0x81,
|
|
||||||
0xD1, 0x82, 0x02, 0x23, 0xDD, 0x18, 0x65, 0x0A, 0x64, 0x25, 0x33, 0x55, 0x60, 0xB2, 0x26, 0xFD,
|
|
||||||
0xE4, 0x0D, 0x15, 0xE8, 0xF0, 0x65, 0x0D, 0xE1, 0xAC, 0xF8, 0xEA, 0xC6, 0xE5, 0x3D, 0xB4, 0xE9,
|
|
||||||
0x1E, 0x4F, 0xD0, 0xF5, 0x72, 0x41, 0xD7, 0x4B, 0xDD, 0x78, 0x72, 0x7E, 0x29, 0x1B, 0x09, 0x14,
|
|
||||||
0x6F, 0xA2, 0x4D, 0x78, 0x45, 0x33, 0x88, 0xF6, 0x85, 0x7F, 0x42, 0xF0, 0x4E, 0xE6, 0x58, 0x92,
|
|
||||||
0xBA, 0x9A, 0x31, 0x5D, 0x68, 0xC8, 0xC3, 0x01, 0xD3, 0x4A, 0xEF, 0x3C, 0x0C, 0xAB, 0x8C, 0xE4,
|
|
||||||
0xAD, 0x4B, 0xA5, 0xFD, 0xF3, 0x73, 0x85, 0x06, 0x8A, 0xF8, 0x0F, 0x03, 0x4A, 0x90, 0xED, 0x50,
|
|
||||||
0x55, 0xE4, 0x26, 0x72, 0x05, 0xF3, 0x7F, 0xCB, 0x01, 0x21, 0xA5, 0xB0, 0x1E, 0x09, 0x15, 0x17,
|
|
||||||
0xF3, 0xFD, 0x1B, 0xF8, 0x88, 0x63, 0x4F, 0x89, 0xA3, 0x24, 0x5A, 0xE8, 0x26, 0x3F, 0xD2, 0x3A,
|
|
||||||
0xDA, 0x44, 0x37, 0x8E, 0x26, 0xA9, 0x47, 0x41, 0x4B, 0xDE, 0x5B, 0x32, 0x15, 0x41, 0xC7, 0x2F,
|
|
||||||
0x07, 0xD1, 0xF1, 0x4B, 0x41, 0xC7, 0x2F, 0x00, 0xD8, 0x2C, 0x03, 0x7A, 0x52, 0x43, 0x30, 0xA3,
|
|
||||||
0xAA, 0x27, 0xBD, 0x10, 0x5A, 0x57, 0x33, 0xBF, 0xCC, 0x4C, 0x16, 0x95, 0xF2, 0x48, 0x6E, 0xD7,
|
|
||||||
0x3E, 0x3F, 0x16, 0xFF, 0x6A, 0xEE, 0xFF, 0x81, 0x09, 0x07, 0x8B, 0x81, 0x4E, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,780 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>ESP32 OV2460</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial,Helvetica,sans-serif;
|
||||||
|
background: #181818;
|
||||||
|
color: #EFEFEF;
|
||||||
|
font-size: 16px
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 18px
|
||||||
|
}
|
||||||
|
|
||||||
|
section.main {
|
||||||
|
display: flex
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu,section.main {
|
||||||
|
flex-direction: column
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu {
|
||||||
|
display: none;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
min-width: 340px;
|
||||||
|
background: #363636;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: -10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: stretch
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-margin-before: 0;
|
||||||
|
margin-block-start: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
margin-block-end: 0;
|
||||||
|
-webkit-margin-start: 0;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
-webkit-margin-end: 0;
|
||||||
|
margin-inline-end: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
figure img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 800px) and (orientation:landscape) {
|
||||||
|
#content {
|
||||||
|
display:flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: stretch
|
||||||
|
}
|
||||||
|
|
||||||
|
figure img {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: calc(100vh - 40px);
|
||||||
|
width: auto;
|
||||||
|
height: auto
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
padding: 0 0 0 0px;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-margin-before: 0;
|
||||||
|
margin-block-start: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
margin-block-end: 0;
|
||||||
|
-webkit-margin-start: 0;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
-webkit-margin-end: 0;
|
||||||
|
margin-inline-end: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
section#buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-between
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-toggle-cb {
|
||||||
|
outline: 0;
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-toggle-cb:checked+#menu {
|
||||||
|
display: flex
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 5px 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group>label {
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: 10px;
|
||||||
|
min-width: 47%
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input,.input-group select {
|
||||||
|
flex-grow: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.range-max,.range-min {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: block;
|
||||||
|
margin: 5px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border: 0;
|
||||||
|
line-height: 28px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
background: #ff3034;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 16px;
|
||||||
|
outline: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background: #ff494d
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background: #f21c21
|
||||||
|
}
|
||||||
|
|
||||||
|
button.disabled {
|
||||||
|
cursor: default;
|
||||||
|
background: #a0a0a0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range] {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 22px;
|
||||||
|
background: #363636;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus {
|
||||||
|
outline: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #EFEFEF;
|
||||||
|
border-radius: 0;
|
||||||
|
border: 0 solid #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
border: 1px solid rgba(0,0,30,0);
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background: #ff3034;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin-top: -11.5px
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-webkit-slider-runnable-track {
|
||||||
|
background: #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #EFEFEF;
|
||||||
|
border-radius: 0;
|
||||||
|
border: 0 solid #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
border: 1px solid rgba(0,0,30,0);
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background: #ff3034;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: 0 0;
|
||||||
|
border-color: transparent;
|
||||||
|
color: transparent
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-lower {
|
||||||
|
background: #EFEFEF;
|
||||||
|
border: 0 solid #EFEFEF;
|
||||||
|
border-radius: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-upper {
|
||||||
|
background: #EFEFEF;
|
||||||
|
border: 0 solid #EFEFEF;
|
||||||
|
border-radius: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-thumb {
|
||||||
|
border: 1px solid rgba(0,0,30,0);
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background: #ff3034;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 2px
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-ms-fill-lower {
|
||||||
|
background: #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-ms-fill-upper {
|
||||||
|
background: #363636
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
line-height: 22px;
|
||||||
|
font-size: 16px;
|
||||||
|
height: 22px
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input {
|
||||||
|
outline: 0;
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
width: 50px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 22px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: grey
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider,.slider:before {
|
||||||
|
display: inline-block;
|
||||||
|
transition: .4s
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:before {
|
||||||
|
position: relative;
|
||||||
|
content: "";
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
left: 4px;
|
||||||
|
top: 3px;
|
||||||
|
background-color: #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked+.slider {
|
||||||
|
background-color: #ff3034
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked+.slider:before {
|
||||||
|
-webkit-transform: translateX(26px);
|
||||||
|
transform: translateX(26px)
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
border: 1px solid #363636;
|
||||||
|
font-size: 14px;
|
||||||
|
height: 22px;
|
||||||
|
outline: 0;
|
||||||
|
border-radius: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
position: relative;
|
||||||
|
min-width: 160px
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
background: #ff3034;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 100px;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 18px;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="main">
|
||||||
|
<div id="logo">
|
||||||
|
<label for="nav-toggle-cb" id="nav-toggle">☰ Toggle OV2640 settings</label>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
<div id="sidebar">
|
||||||
|
<input type="checkbox" id="nav-toggle-cb" checked="checked">
|
||||||
|
<nav id="menu">
|
||||||
|
<div class="input-group" id="framesize-group">
|
||||||
|
<label for="framesize">Resolution</label>
|
||||||
|
<select id="framesize" class="default-action">
|
||||||
|
<option value="10">UXGA(1600x1200)</option>
|
||||||
|
<option value="9">SXGA(1280x1024)</option>
|
||||||
|
<option value="8">XGA(1024x768)</option>
|
||||||
|
<option value="7">SVGA(800x600)</option>
|
||||||
|
<option value="6">VGA(640x480)</option>
|
||||||
|
<option value="5" selected="selected">CIF(400x296)</option>
|
||||||
|
<option value="4">QVGA(320x240)</option>
|
||||||
|
<option value="3">HQVGA(240x176)</option>
|
||||||
|
<option value="0">QQVGA(160x120)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="quality-group">
|
||||||
|
<label for="quality">Quality</label>
|
||||||
|
<div class="range-min">10</div>
|
||||||
|
<input type="range" id="quality" min="10" max="63" value="10" class="default-action">
|
||||||
|
<div class="range-max">63</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="brightness-group">
|
||||||
|
<label for="brightness">Brightness</label>
|
||||||
|
<div class="range-min">-2</div>
|
||||||
|
<input type="range" id="brightness" min="-2" max="2" value="0" class="default-action">
|
||||||
|
<div class="range-max">2</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="contrast-group">
|
||||||
|
<label for="contrast">Contrast</label>
|
||||||
|
<div class="range-min">-2</div>
|
||||||
|
<input type="range" id="contrast" min="-2" max="2" value="0" class="default-action">
|
||||||
|
<div class="range-max">2</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="saturation-group">
|
||||||
|
<label for="saturation">Saturation</label>
|
||||||
|
<div class="range-min">-2</div>
|
||||||
|
<input type="range" id="saturation" min="-2" max="2" value="0" class="default-action">
|
||||||
|
<div class="range-max">2</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="special_effect-group">
|
||||||
|
<label for="special_effect">Special Effect</label>
|
||||||
|
<select id="special_effect" class="default-action">
|
||||||
|
<option value="0" selected="selected">No Effect</option>
|
||||||
|
<option value="1">Negative</option>
|
||||||
|
<option value="2">Grayscale</option>
|
||||||
|
<option value="3">Red Tint</option>
|
||||||
|
<option value="4">Green Tint</option>
|
||||||
|
<option value="5">Blue Tint</option>
|
||||||
|
<option value="6">Sepia</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="awb-group">
|
||||||
|
<label for="awb">AWB</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="awb" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="awb"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="awb_gain-group">
|
||||||
|
<label for="awb_gain">AWB Gain</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="awb_gain" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="awb_gain"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="wb_mode-group">
|
||||||
|
<label for="wb_mode">WB Mode</label>
|
||||||
|
<select id="wb_mode" class="default-action">
|
||||||
|
<option value="0" selected="selected">Auto</option>
|
||||||
|
<option value="1">Sunny</option>
|
||||||
|
<option value="2">Cloudy</option>
|
||||||
|
<option value="3">Office</option>
|
||||||
|
<option value="4">Home</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="aec-group">
|
||||||
|
<label for="aec">AEC SENSOR</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="aec" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="aec"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="aec2-group">
|
||||||
|
<label for="aec2">AEC DSP</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="aec2" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="aec2"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="ae_level-group">
|
||||||
|
<label for="ae_level">AE Level</label>
|
||||||
|
<div class="range-min">-2</div>
|
||||||
|
<input type="range" id="ae_level" min="-2" max="2" value="0" class="default-action">
|
||||||
|
<div class="range-max">2</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="aec_value-group">
|
||||||
|
<label for="aec_value">Exposure</label>
|
||||||
|
<div class="range-min">0</div>
|
||||||
|
<input type="range" id="aec_value" min="0" max="1200" value="204" class="default-action">
|
||||||
|
<div class="range-max">1200</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="agc-group">
|
||||||
|
<label for="agc">AGC</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="agc" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="agc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group hidden" id="agc_gain-group">
|
||||||
|
<label for="agc_gain">Gain</label>
|
||||||
|
<div class="range-min">1x</div>
|
||||||
|
<input type="range" id="agc_gain" min="0" max="30" value="5" class="default-action">
|
||||||
|
<div class="range-max">31x</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="gainceiling-group">
|
||||||
|
<label for="gainceiling">Gain Ceiling</label>
|
||||||
|
<div class="range-min">2x</div>
|
||||||
|
<input type="range" id="gainceiling" min="0" max="6" value="0" class="default-action">
|
||||||
|
<div class="range-max">128x</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="bpc-group">
|
||||||
|
<label for="bpc">BPC</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="bpc" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="bpc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="wpc-group">
|
||||||
|
<label for="wpc">WPC</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="wpc" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="wpc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="raw_gma-group">
|
||||||
|
<label for="raw_gma">Raw GMA</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="raw_gma" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="raw_gma"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="lenc-group">
|
||||||
|
<label for="lenc">Lens Correction</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="lenc" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="lenc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="hmirror-group">
|
||||||
|
<label for="hmirror">H-Mirror</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="hmirror" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="hmirror"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="vflip-group">
|
||||||
|
<label for="vflip">V-Flip</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="vflip" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="vflip"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="dcw-group">
|
||||||
|
<label for="dcw">DCW (Downsize EN)</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="dcw" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="dcw"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="colorbar-group">
|
||||||
|
<label for="colorbar">Color Bar</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="colorbar" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="colorbar"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="face_detect-group">
|
||||||
|
<label for="face_detect">Face Detection</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="face_detect" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="face_detect"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="face_recognize-group">
|
||||||
|
<label for="face_recognize">Face Recognition</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="face_recognize" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="face_recognize"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section id="buttons">
|
||||||
|
<button id="get-still">Get Still</button>
|
||||||
|
<button id="toggle-stream">Start Stream</button>
|
||||||
|
<button id="face_enroll" class="disabled" disabled="disabled">Enroll Face</button>
|
||||||
|
</section>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<figure>
|
||||||
|
<div id="stream-container" class="image-container hidden">
|
||||||
|
<div class="close" id="close-stream">×</div>
|
||||||
|
<img id="stream" src="">
|
||||||
|
</div>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function (event) {
|
||||||
|
var baseHost = document.location.origin
|
||||||
|
var streamUrl = baseHost + ':81'
|
||||||
|
|
||||||
|
const hide = el => {
|
||||||
|
el.classList.add('hidden')
|
||||||
|
}
|
||||||
|
const show = el => {
|
||||||
|
el.classList.remove('hidden')
|
||||||
|
}
|
||||||
|
|
||||||
|
const disable = el => {
|
||||||
|
el.classList.add('disabled')
|
||||||
|
el.disabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const enable = el => {
|
||||||
|
el.classList.remove('disabled')
|
||||||
|
el.disabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateValue = (el, value, updateRemote) => {
|
||||||
|
updateRemote = updateRemote == null ? true : updateRemote
|
||||||
|
let initialValue
|
||||||
|
if (el.type === 'checkbox') {
|
||||||
|
initialValue = el.checked
|
||||||
|
value = !!value
|
||||||
|
el.checked = value
|
||||||
|
} else {
|
||||||
|
initialValue = el.value
|
||||||
|
el.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateRemote && initialValue !== value) {
|
||||||
|
updateConfig(el);
|
||||||
|
} else if(!updateRemote){
|
||||||
|
if(el.id === "aec"){
|
||||||
|
value ? hide(exposure) : show(exposure)
|
||||||
|
} else if(el.id === "agc"){
|
||||||
|
if (value) {
|
||||||
|
show(gainCeiling)
|
||||||
|
hide(agcGain)
|
||||||
|
} else {
|
||||||
|
hide(gainCeiling)
|
||||||
|
show(agcGain)
|
||||||
|
}
|
||||||
|
} else if(el.id === "awb_gain"){
|
||||||
|
value ? show(wb) : hide(wb)
|
||||||
|
} else if(el.id === "face_recognize"){
|
||||||
|
value ? enable(enrollButton) : disable(enrollButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateConfig (el) {
|
||||||
|
let value
|
||||||
|
switch (el.type) {
|
||||||
|
case 'checkbox':
|
||||||
|
value = el.checked ? 1 : 0
|
||||||
|
break
|
||||||
|
case 'range':
|
||||||
|
case 'select-one':
|
||||||
|
value = el.value
|
||||||
|
break
|
||||||
|
case 'button':
|
||||||
|
case 'submit':
|
||||||
|
value = '1'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `${baseHost}/control?var=${el.id}&val=${value}`
|
||||||
|
|
||||||
|
fetch(query)
|
||||||
|
.then(response => {
|
||||||
|
console.log(`request to ${query} finished, status: ${response.status}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll('.close')
|
||||||
|
.forEach(el => {
|
||||||
|
el.onclick = () => {
|
||||||
|
hide(el.parentNode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// read initial values
|
||||||
|
fetch(`${baseHost}/status`)
|
||||||
|
.then(function (response) {
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then(function (state) {
|
||||||
|
document
|
||||||
|
.querySelectorAll('.default-action')
|
||||||
|
.forEach(el => {
|
||||||
|
updateValue(el, state[el.id], false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const view = document.getElementById('stream')
|
||||||
|
const viewContainer = document.getElementById('stream-container')
|
||||||
|
const stillButton = document.getElementById('get-still')
|
||||||
|
const streamButton = document.getElementById('toggle-stream')
|
||||||
|
const enrollButton = document.getElementById('face_enroll')
|
||||||
|
const closeButton = document.getElementById('close-stream')
|
||||||
|
|
||||||
|
const stopStream = () => {
|
||||||
|
window.stop();
|
||||||
|
streamButton.innerHTML = 'Start Stream'
|
||||||
|
}
|
||||||
|
|
||||||
|
const startStream = () => {
|
||||||
|
view.src = `${streamUrl}/stream`
|
||||||
|
show(viewContainer)
|
||||||
|
streamButton.innerHTML = 'Stop Stream'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach actions to buttons
|
||||||
|
stillButton.onclick = () => {
|
||||||
|
stopStream()
|
||||||
|
view.src = `${baseHost}/capture?_cb=${Date.now()}`
|
||||||
|
show(viewContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
closeButton.onclick = () => {
|
||||||
|
stopStream()
|
||||||
|
hide(viewContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
streamButton.onclick = () => {
|
||||||
|
const streamEnabled = streamButton.innerHTML === 'Stop Stream'
|
||||||
|
if (streamEnabled) {
|
||||||
|
stopStream()
|
||||||
|
} else {
|
||||||
|
startStream()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enrollButton.onclick = () => {
|
||||||
|
updateConfig(enrollButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach default on change action
|
||||||
|
document
|
||||||
|
.querySelectorAll('.default-action')
|
||||||
|
.forEach(el => {
|
||||||
|
el.onchange = () => updateConfig(el)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Custom actions
|
||||||
|
// Gain
|
||||||
|
const agc = document.getElementById('agc')
|
||||||
|
const agcGain = document.getElementById('agc_gain-group')
|
||||||
|
const gainCeiling = document.getElementById('gainceiling-group')
|
||||||
|
agc.onchange = () => {
|
||||||
|
updateConfig(agc)
|
||||||
|
if (agc.checked) {
|
||||||
|
show(gainCeiling)
|
||||||
|
hide(agcGain)
|
||||||
|
} else {
|
||||||
|
hide(gainCeiling)
|
||||||
|
show(agcGain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exposure
|
||||||
|
const aec = document.getElementById('aec')
|
||||||
|
const exposure = document.getElementById('aec_value-group')
|
||||||
|
aec.onchange = () => {
|
||||||
|
updateConfig(aec)
|
||||||
|
aec.checked ? hide(exposure) : show(exposure)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AWB
|
||||||
|
const awb = document.getElementById('awb_gain')
|
||||||
|
const wb = document.getElementById('wb_mode-group')
|
||||||
|
awb.onchange = () => {
|
||||||
|
updateConfig(awb)
|
||||||
|
awb.checked ? show(wb) : hide(wb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detection and framesize
|
||||||
|
const detect = document.getElementById('face_detect')
|
||||||
|
const recognize = document.getElementById('face_recognize')
|
||||||
|
const framesize = document.getElementById('framesize')
|
||||||
|
|
||||||
|
framesize.onchange = () => {
|
||||||
|
updateConfig(framesize)
|
||||||
|
if (framesize.value > 5) {
|
||||||
|
updateValue(detect, false)
|
||||||
|
updateValue(recognize, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
detect.onchange = () => {
|
||||||
|
if (framesize.value > 5) {
|
||||||
|
alert("Please select CIF or lower resolution before enabling this feature!");
|
||||||
|
updateValue(detect, false)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateConfig(detect)
|
||||||
|
if (!detect.checked) {
|
||||||
|
disable(enrollButton)
|
||||||
|
updateValue(recognize, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
recognize.onchange = () => {
|
||||||
|
if (framesize.value > 5) {
|
||||||
|
alert("Please select CIF or lower resolution before enabling this feature!");
|
||||||
|
updateValue(recognize, false)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateConfig(recognize)
|
||||||
|
if (recognize.checked) {
|
||||||
|
enable(enrollButton)
|
||||||
|
updateValue(detect, true)
|
||||||
|
} else {
|
||||||
|
disable(enrollButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Binary file not shown.
|
@ -0,0 +1,804 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>ESP32 OV3660</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial,Helvetica,sans-serif;
|
||||||
|
background: #181818;
|
||||||
|
color: #EFEFEF;
|
||||||
|
font-size: 16px
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 18px
|
||||||
|
}
|
||||||
|
|
||||||
|
section.main {
|
||||||
|
display: flex
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu,section.main {
|
||||||
|
flex-direction: column
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu {
|
||||||
|
display: none;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
min-width: 340px;
|
||||||
|
background: #363636;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: -10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: stretch
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-margin-before: 0;
|
||||||
|
margin-block-start: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
margin-block-end: 0;
|
||||||
|
-webkit-margin-start: 0;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
-webkit-margin-end: 0;
|
||||||
|
margin-inline-end: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
figure img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 800px) and (orientation:landscape) {
|
||||||
|
#content {
|
||||||
|
display:flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: stretch
|
||||||
|
}
|
||||||
|
|
||||||
|
figure img {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: calc(100vh - 40px);
|
||||||
|
width: auto;
|
||||||
|
height: auto
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
padding: 0 0 0 0px;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-margin-before: 0;
|
||||||
|
margin-block-start: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
margin-block-end: 0;
|
||||||
|
-webkit-margin-start: 0;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
-webkit-margin-end: 0;
|
||||||
|
margin-inline-end: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
section#buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-between
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-toggle-cb {
|
||||||
|
outline: 0;
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-toggle-cb:checked+#menu {
|
||||||
|
display: flex
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 5px 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group>label {
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: 10px;
|
||||||
|
min-width: 47%
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input,.input-group select {
|
||||||
|
flex-grow: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.range-max,.range-min {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: block;
|
||||||
|
margin: 5px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border: 0;
|
||||||
|
line-height: 28px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
background: #ff3034;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 16px;
|
||||||
|
outline: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background: #ff494d
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background: #f21c21
|
||||||
|
}
|
||||||
|
|
||||||
|
button.disabled {
|
||||||
|
cursor: default;
|
||||||
|
background: #a0a0a0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range] {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 22px;
|
||||||
|
background: #363636;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus {
|
||||||
|
outline: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #EFEFEF;
|
||||||
|
border-radius: 0;
|
||||||
|
border: 0 solid #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
border: 1px solid rgba(0,0,30,0);
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background: #ff3034;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin-top: -11.5px
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-webkit-slider-runnable-track {
|
||||||
|
background: #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #EFEFEF;
|
||||||
|
border-radius: 0;
|
||||||
|
border: 0 solid #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
border: 1px solid rgba(0,0,30,0);
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background: #ff3034;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: 0 0;
|
||||||
|
border-color: transparent;
|
||||||
|
color: transparent
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-lower {
|
||||||
|
background: #EFEFEF;
|
||||||
|
border: 0 solid #EFEFEF;
|
||||||
|
border-radius: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-upper {
|
||||||
|
background: #EFEFEF;
|
||||||
|
border: 0 solid #EFEFEF;
|
||||||
|
border-radius: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-thumb {
|
||||||
|
border: 1px solid rgba(0,0,30,0);
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 50px;
|
||||||
|
background: #ff3034;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 2px
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-ms-fill-lower {
|
||||||
|
background: #EFEFEF
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-ms-fill-upper {
|
||||||
|
background: #363636
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
line-height: 22px;
|
||||||
|
font-size: 16px;
|
||||||
|
height: 22px
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input {
|
||||||
|
outline: 0;
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
width: 50px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 22px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: grey
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider,.slider:before {
|
||||||
|
display: inline-block;
|
||||||
|
transition: .4s
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:before {
|
||||||
|
position: relative;
|
||||||
|
content: "";
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
left: 4px;
|
||||||
|
top: 3px;
|
||||||
|
background-color: #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked+.slider {
|
||||||
|
background-color: #ff3034
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked+.slider:before {
|
||||||
|
-webkit-transform: translateX(26px);
|
||||||
|
transform: translateX(26px)
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
border: 1px solid #363636;
|
||||||
|
font-size: 14px;
|
||||||
|
height: 22px;
|
||||||
|
outline: 0;
|
||||||
|
border-radius: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
position: relative;
|
||||||
|
min-width: 160px
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
background: #ff3034;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 100px;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 18px;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
border: 1px solid #363636;
|
||||||
|
font-size: 14px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 1px;
|
||||||
|
outline: 0;
|
||||||
|
border-radius: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-button {
|
||||||
|
line-height: 20px;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 1px 4px 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="main">
|
||||||
|
<div id="logo">
|
||||||
|
<label for="nav-toggle-cb" id="nav-toggle">☰ Toggle OV3660 settings</label>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
<div id="sidebar">
|
||||||
|
<input type="checkbox" id="nav-toggle-cb" checked="checked">
|
||||||
|
<nav id="menu">
|
||||||
|
<div class="input-group" id="framesize-group">
|
||||||
|
<label for="framesize">Resolution</label>
|
||||||
|
<select id="framesize" class="default-action">
|
||||||
|
<option value="11">QXGA(2048x1564)</option>
|
||||||
|
<option value="10">UXGA(1600x1200)</option>
|
||||||
|
<option value="9">SXGA(1280x1024)</option>
|
||||||
|
<option value="8">XGA(1024x768)</option>
|
||||||
|
<option value="7">SVGA(800x600)</option>
|
||||||
|
<option value="6">VGA(640x480)</option>
|
||||||
|
<option value="5" selected="selected">CIF(400x296)</option>
|
||||||
|
<option value="4">QVGA(320x240)</option>
|
||||||
|
<option value="3">HQVGA(240x176)</option>
|
||||||
|
<option value="0">QQVGA(160x120)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="quality-group">
|
||||||
|
<label for="quality">Quality</label>
|
||||||
|
<div class="range-min">4</div>
|
||||||
|
<input type="range" id="quality" min="4" max="63" value="10" class="default-action">
|
||||||
|
<div class="range-max">63</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="brightness-group">
|
||||||
|
<label for="brightness">Brightness</label>
|
||||||
|
<div class="range-min">-3</div>
|
||||||
|
<input type="range" id="brightness" min="-3" max="3" value="0" class="default-action">
|
||||||
|
<div class="range-max">3</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="contrast-group">
|
||||||
|
<label for="contrast">Contrast</label>
|
||||||
|
<div class="range-min">-3</div>
|
||||||
|
<input type="range" id="contrast" min="-3" max="3" value="0" class="default-action">
|
||||||
|
<div class="range-max">3</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="saturation-group">
|
||||||
|
<label for="saturation">Saturation</label>
|
||||||
|
<div class="range-min">-4</div>
|
||||||
|
<input type="range" id="saturation" min="-4" max="4" value="0" class="default-action">
|
||||||
|
<div class="range-max">4</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="sharpness-group">
|
||||||
|
<label for="sharpness">Sharpness</label>
|
||||||
|
<div class="range-min">-3</div>
|
||||||
|
<input type="range" id="sharpness" min="-3" max="3" value="0" class="default-action">
|
||||||
|
<div class="range-max">3</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="denoise-group">
|
||||||
|
<label for="denoise">De-Noise</label>
|
||||||
|
<div class="range-min">Auto</div>
|
||||||
|
<input type="range" id="denoise" min="0" max="8" value="0" class="default-action">
|
||||||
|
<div class="range-max">8</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="ae_level-group">
|
||||||
|
<label for="ae_level">Exposure Level</label>
|
||||||
|
<div class="range-min">-5</div>
|
||||||
|
<input type="range" id="ae_level" min="-5" max="5" value="0" class="default-action">
|
||||||
|
<div class="range-max">5</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="gainceiling-group">
|
||||||
|
<label for="gainceiling">Gainceiling</label>
|
||||||
|
<div class="range-min">0</div>
|
||||||
|
<input type="range" id="gainceiling" min="0" max="511" value="0" class="default-action">
|
||||||
|
<div class="range-max">511</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="special_effect-group">
|
||||||
|
<label for="special_effect">Special Effect</label>
|
||||||
|
<select id="special_effect" class="default-action">
|
||||||
|
<option value="0" selected="selected">No Effect</option>
|
||||||
|
<option value="1">Negative</option>
|
||||||
|
<option value="2">Grayscale</option>
|
||||||
|
<option value="3">Red Tint</option>
|
||||||
|
<option value="4">Green Tint</option>
|
||||||
|
<option value="5">Blue Tint</option>
|
||||||
|
<option value="6">Sepia</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="awb-group">
|
||||||
|
<label for="awb">AWB Enable</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="awb" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="awb"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="dcw-group">
|
||||||
|
<label for="dcw">Advanced AWB</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="dcw" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="dcw"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="awb_gain-group">
|
||||||
|
<label for="awb_gain">Manual AWB</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="awb_gain" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="awb_gain"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="wb_mode-group">
|
||||||
|
<label for="wb_mode">AWB Mode</label>
|
||||||
|
<select id="wb_mode" class="default-action">
|
||||||
|
<option value="0" selected="selected">Auto</option>
|
||||||
|
<option value="1">Sunny</option>
|
||||||
|
<option value="2">Cloudy</option>
|
||||||
|
<option value="3">Office</option>
|
||||||
|
<option value="4">Home</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="aec-group">
|
||||||
|
<label for="aec">AEC Enable</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="aec" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="aec"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="aec_value-group">
|
||||||
|
<label for="aec_value">Manual Exposure</label>
|
||||||
|
<div class="range-min">0</div>
|
||||||
|
<input type="range" id="aec_value" min="0" max="1536" value="320" class="default-action">
|
||||||
|
<div class="range-max">1536</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="aec2-group">
|
||||||
|
<label for="aec2">Night Mode</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="aec2" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="aec2"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="agc-group">
|
||||||
|
<label for="agc">AGC</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="agc" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="agc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group hidden" id="agc_gain-group">
|
||||||
|
<label for="agc_gain">Gain</label>
|
||||||
|
<div class="range-min">1x</div>
|
||||||
|
<input type="range" id="agc_gain" min="0" max="64" value="5" class="default-action">
|
||||||
|
<div class="range-max">64x</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="raw_gma-group">
|
||||||
|
<label for="raw_gma">GMA Enable</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="raw_gma" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="raw_gma"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="lenc-group">
|
||||||
|
<label for="lenc">Lens Correction</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="lenc" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="lenc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="hmirror-group">
|
||||||
|
<label for="hmirror">H-Mirror</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="hmirror" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="hmirror"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="vflip-group">
|
||||||
|
<label for="vflip">V-Flip</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="vflip" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="vflip"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="bpc-group">
|
||||||
|
<label for="bpc">BPC</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="bpc" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="bpc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="wpc-group">
|
||||||
|
<label for="wpc">WPC</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="wpc" type="checkbox" class="default-action" checked="checked">
|
||||||
|
<label class="slider" for="wpc"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="colorbar-group">
|
||||||
|
<label for="colorbar">Color Bar</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="colorbar" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="colorbar"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="face_detect-group">
|
||||||
|
<label for="face_detect">Face Detection</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="face_detect" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="face_detect"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group" id="face_recognize-group">
|
||||||
|
<label for="face_recognize">Face Recognition</label>
|
||||||
|
<div class="switch">
|
||||||
|
<input id="face_recognize" type="checkbox" class="default-action">
|
||||||
|
<label class="slider" for="face_recognize"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section id="buttons">
|
||||||
|
<button id="get-still">Get Still</button>
|
||||||
|
<button id="toggle-stream">Start Stream</button>
|
||||||
|
<button id="face_enroll" class="disabled" disabled="disabled">Enroll Face</button>
|
||||||
|
</section>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<figure>
|
||||||
|
<div id="stream-container" class="image-container hidden">
|
||||||
|
<div class="close" id="close-stream">×</div>
|
||||||
|
<img id="stream" src="">
|
||||||
|
</div>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function (event) {
|
||||||
|
var baseHost = document.location.origin
|
||||||
|
var streamUrl = baseHost + ':81'
|
||||||
|
|
||||||
|
const hide = el => {
|
||||||
|
el.classList.add('hidden')
|
||||||
|
}
|
||||||
|
const show = el => {
|
||||||
|
el.classList.remove('hidden')
|
||||||
|
}
|
||||||
|
|
||||||
|
const disable = el => {
|
||||||
|
el.classList.add('disabled')
|
||||||
|
el.disabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const enable = el => {
|
||||||
|
el.classList.remove('disabled')
|
||||||
|
el.disabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateValue = (el, value, updateRemote) => {
|
||||||
|
updateRemote = updateRemote == null ? true : updateRemote
|
||||||
|
let initialValue
|
||||||
|
if (el.type === 'checkbox') {
|
||||||
|
initialValue = el.checked
|
||||||
|
value = !!value
|
||||||
|
el.checked = value
|
||||||
|
} else {
|
||||||
|
initialValue = el.value
|
||||||
|
el.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateRemote && initialValue !== value) {
|
||||||
|
updateConfig(el);
|
||||||
|
} else if(!updateRemote){
|
||||||
|
if(el.id === "aec"){
|
||||||
|
value ? hide(exposure) : show(exposure)
|
||||||
|
} else if(el.id === "agc"){
|
||||||
|
if (value) {
|
||||||
|
hide(agcGain)
|
||||||
|
} else {
|
||||||
|
show(agcGain)
|
||||||
|
}
|
||||||
|
} else if(el.id === "awb_gain"){
|
||||||
|
value ? show(wb) : hide(wb)
|
||||||
|
} else if(el.id === "face_recognize"){
|
||||||
|
value ? enable(enrollButton) : disable(enrollButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateConfig (el) {
|
||||||
|
let value
|
||||||
|
switch (el.type) {
|
||||||
|
case 'checkbox':
|
||||||
|
value = el.checked ? 1 : 0
|
||||||
|
break
|
||||||
|
case 'range':
|
||||||
|
case 'select-one':
|
||||||
|
value = el.value
|
||||||
|
break
|
||||||
|
case 'button':
|
||||||
|
case 'submit':
|
||||||
|
value = '1'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `${baseHost}/control?var=${el.id}&val=${value}`
|
||||||
|
|
||||||
|
fetch(query)
|
||||||
|
.then(response => {
|
||||||
|
console.log(`request to ${query} finished, status: ${response.status}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll('.close')
|
||||||
|
.forEach(el => {
|
||||||
|
el.onclick = () => {
|
||||||
|
hide(el.parentNode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// read initial values
|
||||||
|
fetch(`${baseHost}/status`)
|
||||||
|
.then(function (response) {
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then(function (state) {
|
||||||
|
document
|
||||||
|
.querySelectorAll('.default-action')
|
||||||
|
.forEach(el => {
|
||||||
|
updateValue(el, state[el.id], false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const view = document.getElementById('stream')
|
||||||
|
const viewContainer = document.getElementById('stream-container')
|
||||||
|
const stillButton = document.getElementById('get-still')
|
||||||
|
const streamButton = document.getElementById('toggle-stream')
|
||||||
|
const enrollButton = document.getElementById('face_enroll')
|
||||||
|
const closeButton = document.getElementById('close-stream')
|
||||||
|
|
||||||
|
const stopStream = () => {
|
||||||
|
window.stop();
|
||||||
|
streamButton.innerHTML = 'Start Stream'
|
||||||
|
}
|
||||||
|
|
||||||
|
const startStream = () => {
|
||||||
|
view.src = `${streamUrl}/stream`
|
||||||
|
show(viewContainer)
|
||||||
|
streamButton.innerHTML = 'Stop Stream'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach actions to buttons
|
||||||
|
stillButton.onclick = () => {
|
||||||
|
stopStream()
|
||||||
|
view.src = `${baseHost}/capture?_cb=${Date.now()}`
|
||||||
|
show(viewContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
closeButton.onclick = () => {
|
||||||
|
stopStream()
|
||||||
|
hide(viewContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
streamButton.onclick = () => {
|
||||||
|
const streamEnabled = streamButton.innerHTML === 'Stop Stream'
|
||||||
|
if (streamEnabled) {
|
||||||
|
stopStream()
|
||||||
|
} else {
|
||||||
|
startStream()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enrollButton.onclick = () => {
|
||||||
|
updateConfig(enrollButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach default on change action
|
||||||
|
document
|
||||||
|
.querySelectorAll('.default-action')
|
||||||
|
.forEach(el => {
|
||||||
|
el.onchange = () => updateConfig(el)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Custom actions
|
||||||
|
// Gain
|
||||||
|
const agc = document.getElementById('agc')
|
||||||
|
const agcGain = document.getElementById('agc_gain-group')
|
||||||
|
agc.onchange = () => {
|
||||||
|
updateConfig(agc)
|
||||||
|
if (agc.checked) {
|
||||||
|
hide(agcGain)
|
||||||
|
} else {
|
||||||
|
show(agcGain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exposure
|
||||||
|
const aec = document.getElementById('aec')
|
||||||
|
const exposure = document.getElementById('aec_value-group')
|
||||||
|
aec.onchange = () => {
|
||||||
|
updateConfig(aec)
|
||||||
|
aec.checked ? hide(exposure) : show(exposure)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AWB
|
||||||
|
const awb = document.getElementById('awb_gain')
|
||||||
|
const wb = document.getElementById('wb_mode-group')
|
||||||
|
awb.onchange = () => {
|
||||||
|
updateConfig(awb)
|
||||||
|
awb.checked ? show(wb) : hide(wb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detection and framesize
|
||||||
|
const detect = document.getElementById('face_detect')
|
||||||
|
const recognize = document.getElementById('face_recognize')
|
||||||
|
const framesize = document.getElementById('framesize')
|
||||||
|
|
||||||
|
framesize.onchange = () => {
|
||||||
|
updateConfig(framesize)
|
||||||
|
if (framesize.value > 5) {
|
||||||
|
updateValue(detect, false)
|
||||||
|
updateValue(recognize, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
detect.onchange = () => {
|
||||||
|
if (framesize.value > 5) {
|
||||||
|
alert("Please select CIF or lower resolution before enabling this feature!");
|
||||||
|
updateValue(detect, false)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateConfig(detect)
|
||||||
|
if (!detect.checked) {
|
||||||
|
disable(enrollButton)
|
||||||
|
updateValue(recognize, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
recognize.onchange = () => {
|
||||||
|
if (framesize.value > 5) {
|
||||||
|
alert("Please select CIF or lower resolution before enabling this feature!");
|
||||||
|
updateValue(recognize, false)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateConfig(recognize)
|
||||||
|
if (recognize.checked) {
|
||||||
|
enable(enrollButton)
|
||||||
|
updateValue(detect, true)
|
||||||
|
} else {
|
||||||
|
disable(enrollButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Binary file not shown.
Loading…
Reference in New Issue