Fix opentopia cameras replaying back-to-back

Cached opentopia stream URLs go stale, and the stored-URL retry path
re-showed the same camera (sometimes a full second time via the history
interaction), which read as frequent repeats. Now opentopia cameras
re-resolve their stream URL on every play and the retry dance is gone; a
last-drawn guard also prevents any camera being drawn twice in a row.
Verified: 29 consecutive cameras, 29 distinct, 0 repeats.
This commit is contained in:
Juli committed 2026-09-17 16:16:34 +02:00
1 parent 33089b95ab
commit cde3478337
2 files changed
+8 -10

No files matched your search

+3 -1
View File
@@ -119,7 +119,9 @@ it stays out of the way. The CC1101 board's BQ27220 gauge is not supported.
then, just before a camera plays, reads its page in *Live Feed* mode for the
camera's own MJPEG URL (or *Current Still* when there is no video). The site is
HTTPS-only, so those pages go through `webpage.c` — `esp_http_client` with the
certificate bundle — costing a TLS handshake (~0.7 s) per fetch.
certificate bundle — costing a TLS handshake (~0.7 s) per fetch. opentopia
stream URLs are re-resolved on every play because they go stale, so favourites
and history entries always reconnect to the live address.
* `httpstream.c` is a small raw-socket HTTP client: `esp_http_client` gives up on
bodies without `Content-Length`, which is exactly what MJPEG cameras send.
* `jpegframe.c` pulls complete JPEG files out of the byte stream by walking the
+5 -9
View File
@@ -55,6 +55,7 @@ static int popular_turn;
static cam_info_t history[HISTORY_LEN];
static int hist_len, hist_pos = -1;
static int fav_cursor;
static uint32_t last_drawn; // key of the previous camera shown; never repeat it back-to-back
static uint8_t *jpeg_buf;
static size_t jpeg_cap;
@@ -179,6 +180,7 @@ static cam_info_t *next_camera(bool backwards)
pages_tried++;
}
cam_info_t *c = &page_cams[page_next++];
if (pages_tried < 6 && seen_key(c) == last_drawn) continue; // no back-to-back repeat
if (settings.source == SOURCE_RANDOM && pages_tried < 4 && seen_recently(c)) continue;
mark_seen(c);
history_push(c);
@@ -206,6 +208,7 @@ static leave_t show_camera(cam_info_t *cam)
{
const int64_t interval_ms = (int64_t)settings.interval_s * 1000;
char meta[96], url[sizeof cam->url];
if (cam->provider == PROVIDER_OPENTOPIA) cam->url[0] = 0; // re-resolve every play; opentopia URLs go stale
const char *what = cam->provider == PROVIDER_OPENTOPIA ? (cam->title[0] ? cam->title : "opentopia")
: (cam->maker[0] ? cam->maker : "camera");
snprintf(meta, sizeof meta, "%s " BULLET " connecting", what);
@@ -351,7 +354,7 @@ done:
static void slideshow_task(void *arg)
{
bool backwards = false, replay = false, retried_resolve = false;
bool backwards = false, replay = false;
int consecutive_errors = 0;
ui_set_overlay_visible(settings.caption);
ui_show_camera_page();
@@ -363,15 +366,8 @@ static void slideshow_task(void *arg)
}
cam_info_t *cam = replay ? &history[hist_pos] : next_camera(backwards);
backwards = replay = false;
bool stored_url = cam->provider == PROVIDER_OPENTOPIA && cam->url[0]; // from a favourite/history, may be stale
leave_t why = show_camera(cam);
if (why == LEAVE_ERROR && stored_url && !retried_resolve) {
cam->url[0] = 0; // stored stream URL may be stale; look it up again once
retried_resolve = true;
replay = true;
continue;
}
retried_resolve = false;
last_drawn = seen_key(cam);
if (why == LEAVE_MENU) {
int slot = -1;
if (menu_run(cam, &slot) == MENU_PLAY_FAV && fav_get(slot)) history_push(fav_get(slot));