mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 03:54:17 +02:00
feat(camera): optional snapshot URL override for external cameras (#1177)
go2rtc and several IP cameras still emit a warm-up / black frame on every fresh MJPEG connection — even with the v0.2.4b2 warm-up-skip fix it slipped through intermittently for @nkm8's setup. His own bisect named the clean solution: go2rtc exposes /api/frame.jpeg as a dedicated single-frame endpoint that never returns the encoder's stale keyframe. Adds an optional external_camera_snapshot_url column on printers. When set, every single-frame capture path (snapshot endpoint, [SNAPSHOT] notification thumbnails, [PHOTO-BG] finish photo, layer timelapse, Obico ML, plate-detect / calibrate-plate) routes through _capture_snapshot on the override URL via plain HTTP GET, bypassing the warm-up dance. Live view stays on the configured stream URL — only single-frame captures use the override. Override is camera-type-agnostic. SSRF guard applies (existing _sanitize_camera_url allowlist). Empty string treated as unset. Settings UI: new "Snapshot URL (optional)" input + Test button under External Cameras, hidden for camera_type=snapshot since the live URL is already a single-frame source. en + de fully translated; 6 other locales seeded with English copy. 5 backend tests pin the routing contract; 3 frontend tests pin the input + debounced PATCH. Documented in bambuddy-wiki/docs/features/camera.md with the go2rtc example.
This commit is contained in:
@@ -792,7 +792,12 @@ async def camera_snapshot(
|
||||
if printer.external_camera_enabled and printer.external_camera_url:
|
||||
from backend.app.services.external_camera import capture_frame
|
||||
|
||||
frame_data = await capture_frame(printer.external_camera_url, printer.external_camera_type, timeout=15)
|
||||
frame_data = await capture_frame(
|
||||
printer.external_camera_url,
|
||||
printer.external_camera_type,
|
||||
timeout=15,
|
||||
snapshot_url=printer.external_camera_snapshot_url,
|
||||
)
|
||||
if not frame_data:
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
@@ -1040,6 +1045,7 @@ async def check_plate_empty(
|
||||
external_camera_type=printer.external_camera_type if printer.external_camera_enabled else None,
|
||||
use_external=use_external,
|
||||
roi=roi,
|
||||
external_camera_snapshot_url=printer.external_camera_snapshot_url if printer.external_camera_enabled else None,
|
||||
)
|
||||
|
||||
# Get reference count for the response
|
||||
@@ -1124,6 +1130,7 @@ async def calibrate_plate_detection(
|
||||
external_camera_url=printer.external_camera_url if printer.external_camera_enabled else None,
|
||||
external_camera_type=printer.external_camera_type if printer.external_camera_enabled else None,
|
||||
use_external=use_external,
|
||||
external_camera_snapshot_url=printer.external_camera_snapshot_url if printer.external_camera_enabled else None,
|
||||
)
|
||||
|
||||
if light_warning and success:
|
||||
|
||||
Reference in New Issue
Block a user