|
| 1 | +# Storebaelt Webcam Poster Integration Status and UX Options |
| 2 | + |
| 3 | +**Date:** 2026-06-03 |
| 4 | +**Scope:** Storebaelt public traffic/weather webcam publisher behavior, image freshness semantics, and UI/UX optimization options. |
| 5 | + |
| 6 | +## Current Integration Behavior |
| 7 | + |
| 8 | +The Storebaelt integration is intentionally conservative: it publishes references to the two stable poster JPEG URLs, not frames pulled from the HLS live video stream. |
| 9 | + |
| 10 | +For each 5 minute publisher cycle, the runtime: |
| 11 | + |
| 12 | +1. Fetches the poster JPEG bytes from: |
| 13 | + - `https://stream.sob.m-dn.net/res/sb1-live.jpg` |
| 14 | + - `https://stream.sob.m-dn.net/res/sb2-live.jpg` |
| 15 | +2. Computes a SHA-256 hash of the JPEG bytes. |
| 16 | +3. Uses the current poll time as `phenomenonTime`. |
| 17 | +4. Publishes an observation only if the image hash is new for that running service process. |
| 18 | + |
| 19 | +That final dedupe step explains why the Explorer UI can show a latest image observation that is 20+ minutes old. If Storebaelt's poster JPEG endpoint keeps serving the exact same image bytes, the publisher treats it as unchanged and skips publishing duplicates. |
| 20 | + |
| 21 | +This is deliberate data hygiene. It avoids filling CSAPI with repeated observations that point to the same still image while implying that new image content was captured. |
| 22 | + |
| 23 | +## Why It Works This Way |
| 24 | + |
| 25 | +The poster JPEG endpoint has weak capture metadata. During deployment, the HTTP `Last-Modified` header was observed to be stale from 2022, so it cannot be trusted as the camera capture time. |
| 26 | + |
| 27 | +Hashing the actual image bytes is currently the most reliable way to know whether the still image changed. |
| 28 | + |
| 29 | +The current integration is therefore best described as a **latest available poster image reference publisher**, not a true live webcam frame publisher. |
| 30 | + |
| 31 | +If the image is more than 20 minutes old, one of these is probably true: |
| 32 | + |
| 33 | +- Storebaelt's poster JPEG endpoint only refreshes intermittently. |
| 34 | +- The camera/player backend is paused, cached, or only updating the HLS stream while leaving poster JPEGs stale. |
| 35 | +- The browser/player may show fresher HLS video, but the poster JPEG resource currently ingested by OSHConnect has not changed. |
| 36 | + |
| 37 | +This is not necessarily a publisher failure. It means the current source surface is stable but not guaranteed live. |
| 38 | + |
| 39 | +## Optimization Options |
| 40 | + |
| 41 | +### 1. Add Freshness and Status Fields |
| 42 | + |
| 43 | +Add explicit freshness fields to Storebaelt webcam observations, for example: |
| 44 | + |
| 45 | +- `sourceAgeSeconds` |
| 46 | +- `imageChanged` |
| 47 | +- `firstSeenTime` |
| 48 | +- `lastSeenTime` |
| 49 | +- `lastChangedTime` |
| 50 | +- `unchangedPollCount` |
| 51 | +- `stalenessStatus`: `fresh`, `unchanged`, `stale`, or `unavailable` |
| 52 | +- `playerUrl` |
| 53 | +- `pageUrl` |
| 54 | + |
| 55 | +This would let the UI say "image unchanged for 22 min" instead of forcing users to infer that state from the latest observation timestamp. |
| 56 | + |
| 57 | +### 2. Publish Heartbeat Observations |
| 58 | + |
| 59 | +Instead of skipping unchanged hashes entirely, publish a lightweight observation every cycle with the same image URL and hash but `imageChanged: false`. |
| 60 | + |
| 61 | +Benefits: |
| 62 | + |
| 63 | +- The UI always shows that the publisher is alive. |
| 64 | +- Users can distinguish "service polling successfully but camera unchanged" from "publisher stopped." |
| 65 | +- The latest observation can represent latest poll/check time, while separate fields represent image content freshness. |
| 66 | + |
| 67 | +Tradeoffs: |
| 68 | + |
| 69 | +- More observations are stored. |
| 70 | +- The UI must distinguish poll time from image-change time, otherwise latest observation time could be mistaken for latest camera frame time. |
| 71 | + |
| 72 | +For the current demo UX, heartbeat observations are likely the highest-value improvement. |
| 73 | + |
| 74 | +### 3. Keep Dedupe but Expose Service Health Separately |
| 75 | + |
| 76 | +The publisher could keep the current clean observation stream and expose health/status elsewhere. |
| 77 | + |
| 78 | +This preserves observation sparsity, but the Explorer is already observation-oriented, so this option may be less visible and less useful to users unless paired with additional UI work. |
| 79 | + |
| 80 | +### 4. Investigate HLS / Media Playlist Ingestion |
| 81 | + |
| 82 | +The embedded Mediathand/Video.js player likely uses live HLS streams. A deeper integration could ingest one of these instead: |
| 83 | + |
| 84 | +- current HLS playlist URL |
| 85 | +- latest HLS segment URL |
| 86 | +- periodic frame extraction from the stream |
| 87 | +- generated thumbnails from the stream |
| 88 | + |
| 89 | +Benefits: |
| 90 | + |
| 91 | +- More genuinely live webcam behavior. |
| 92 | +- Better fit for a resource users perceive as a live video feed. |
| 93 | + |
| 94 | +Tradeoffs: |
| 95 | + |
| 96 | +- More brittle than stable poster JPEG URLs. |
| 97 | +- Higher bandwidth and CPU cost. |
| 98 | +- Possible CORS, token, caching, or player-provider changes. |
| 99 | +- Requires a policy decision about whether OSHConnect stores derived images or only publishes references. |
| 100 | + |
| 101 | +This should be treated as a second-phase enhancement, not the default first fix. |
| 102 | + |
| 103 | +### 5. Improve Explorer UI for Webcam Deployments |
| 104 | + |
| 105 | +For Storebaelt webcam deployments, the Explorer card should show: |
| 106 | + |
| 107 | +- latest poster image |
| 108 | +- "last checked" time |
| 109 | +- "image changed" time |
| 110 | +- "unchanged for X min" |
| 111 | +- a stale badge beyond a threshold such as 15 or 30 minutes |
| 112 | +- link to the embedded live player |
| 113 | +- link to the public Storebaelt webcam page |
| 114 | + |
| 115 | +This makes the user experience honest and robust even when the poster endpoint stalls. |
| 116 | + |
| 117 | +## Recommended Path |
| 118 | + |
| 119 | +Recommended implementation order: |
| 120 | + |
| 121 | +1. Change the publisher to publish heartbeat/status observations every 5 minutes. |
| 122 | +2. Preserve `imageSha256`, `imageChanged`, `firstSeenTime`, `lastChangedTime`, and latest poll/check time in the result payload. |
| 123 | +3. Update the datastream schema to include those fields. |
| 124 | +4. Update Explorer's deployed-system card to display "last checked" separately from "image changed." |
| 125 | +5. Add a stale badge when the same image has persisted longer than a threshold. |
| 126 | +6. Research HLS extraction only after the poster-source UX is truthful and useful. |
| 127 | + |
| 128 | +This gives a better user experience without prematurely building a fragile video ingestion pipeline. |
0 commit comments