Skip to content

Commit 5e5730e

Browse files
authored
Merge pull request #22 from piotrpdev/OKO-103-ESP32-CAM-Image-Streaming
2 parents b46186d + 1c3c854 commit 5e5730e

2 files changed

Lines changed: 58 additions & 9 deletions

File tree

backend/src/web/app.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const EXPIRED_SESSION_DELETION_INTERVAL: tokio::time::Duration =
6262
tokio::time::Duration::from_secs(60);
6363
const SESSION_DURATION: Duration = Duration::days(1);
6464
const CAMERA_INDICATOR_TEXT: &str = "camera";
65+
const CAMERA_ANY_PORT_INDICATOR_TEXT: &str = "camera_any_port";
6566
const EMPTY_TASK_SLEEP_DURATION: tokio::time::Duration = tokio::time::Duration::from_millis(100);
6667

6768
#[derive(RustEmbed, Clone)]
@@ -278,6 +279,7 @@ async fn handle_socket(
278279
// Always ignoring the first message in every task is maybe not the best solution.
279280

280281
let mut is_camera = false;
282+
let mut camera_any_port = false;
281283
let mut camera_id: i64 = -1;
282284

283285
if let Some(msg) = socket.recv().await {
@@ -291,6 +293,11 @@ async fn handle_socket(
291293
if msg_txt == CAMERA_INDICATOR_TEXT {
292294
info!("{who} is a camera...");
293295
is_camera = true;
296+
} else if msg_txt == CAMERA_ANY_PORT_INDICATOR_TEXT {
297+
// TODO: Maybe find a better way to handle this
298+
info!("{who} is a camera (any port)...");
299+
is_camera = true;
300+
camera_any_port = true;
294301
} else {
295302
info!("{who} is not camera...");
296303
}
@@ -308,14 +315,28 @@ async fn handle_socket(
308315
let mut cameras: Vec<CameraPermissionView> = Vec::new();
309316

310317
if is_camera {
311-
let Ok(db_camera) = Camera::get_using_ip(&auth_session.backend.db, who.to_string()).await
312-
else {
313-
// TODO: Inform client/db if camera not found (both web user and ws connection), also find better way to exit here?
314-
error!("Camera not found in DB, aborting...");
315-
return;
316-
};
318+
// TODO: Maybe find a better way to handle this
319+
if camera_any_port {
320+
let Ok(db_camera) =
321+
Camera::get_using_ip(&auth_session.backend.db, who.ip().to_string() + ":*").await
322+
else {
323+
// TODO: Inform client/db if camera not found (both web user and ws connection), also find better way to exit here?
324+
error!("Camera (any port) not found in DB, aborting...");
325+
return;
326+
};
317327

318-
camera_id = db_camera.camera_id;
328+
camera_id = db_camera.camera_id;
329+
} else {
330+
let Ok(db_camera) =
331+
Camera::get_using_ip(&auth_session.backend.db, who.to_string()).await
332+
else {
333+
// TODO: Inform client/db if camera not found (both web user and ws connection), also find better way to exit here?
334+
error!("Camera not found in DB, aborting...");
335+
return;
336+
};
337+
338+
camera_id = db_camera.camera_id;
339+
}
319340
} else {
320341
// TODO: Return errors to user
321342
let Some(user) = auth_session.user else {

camera/camera.ino

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ static bool needs_setup = true;
5555

5656
static websockets::WebsocketsClient client;
5757

58+
#define CAPTURE_INTERVAL 100
59+
unsigned long previousMillis = 0;
60+
5861
esp_err_t setupCamera() {
5962
camera_config_t config;
6063
config.ledc_channel = LEDC_CHANNEL_0;
@@ -188,10 +191,35 @@ void startWebSocketConnection() {
188191
return;
189192
}
190193

191-
bool connected = client.connect("ws://" + pref_oko + "/");
194+
bool connected = client.connect("ws://" + pref_oko + "/api/ws");
192195
if (connected) {
193196
Serial.println("Connected!");
194-
client.send("Hello Server");
197+
client.send("camera_any_port");
198+
sleep(2);
199+
200+
camera_fb_t *fb = NULL;
201+
202+
// TODO: Move into loop() ?
203+
while (true) {
204+
unsigned long currentMillis = millis();
205+
206+
if (currentMillis - previousMillis >= CAPTURE_INTERVAL) {
207+
previousMillis = currentMillis;
208+
209+
fb = esp_camera_fb_get();
210+
if (!fb) {
211+
Serial.println("Camera capture failed");
212+
continue;
213+
}
214+
215+
// https://github.com/gilmaimon/ArduinoWebsockets/issues/16
216+
// TODO: try streaming? e.g. .streamBinary()
217+
client.sendBinary((const char *)fb->buf, fb->len);
218+
219+
esp_camera_fb_return(fb);
220+
fb = NULL;
221+
}
222+
}
195223
} else {
196224
// Remmember to check firewall
197225
Serial.println("Not Connected!");

0 commit comments

Comments
 (0)