Webcam: Buttons fuer Kamera-Aufloesung (VGA/SVGA)

Schaltet die ESP32-CAM-Aufloesung per Button um (VGA 640x480 = mehr FPS,
SVGA 800x600 = mehr Detail). Server proxyt den /control-Aufruf an die
Kamera (Host automatisch aus CAMERA_URL, Port 80).

- /api/cam_framesize (Whitelist 10=VGA, 11=SVGA)
- zwei Buttons + Status-Feedback im Frontend

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 17:09:46 +02:00
parent b50a2d3316
commit 07c0e44cd8
2 changed files with 57 additions and 0 deletions

33
app.py
View File

@@ -6,6 +6,7 @@ import threading
from datetime import datetime
from zoneinfo import ZoneInfo
from threading import Event, Lock, Condition
from urllib.parse import urlparse
import cv2
import numpy as np
@@ -839,6 +840,38 @@ def grabber_toggle():
return jsonify({"paused": paused})
# Erlaubte framesize-Werte der ESP32-CAM (OV2640): Wert -> Label.
FRAMESIZES = {10: "VGA 640x480", 11: "SVGA 800x600"}
@app.route("/api/cam_framesize", methods=["POST"])
def cam_framesize():
"""Setzt die Aufloesung der ESP32-CAM ueber deren /control-Endpoint.
Der Server proxyt den Aufruf (Browser braucht keinen Direktzugriff)."""
data = request.get_json(silent=True) or {}
try:
val = int(data.get("val"))
except (TypeError, ValueError):
abort(400, description="val (int) erforderlich")
if val not in FRAMESIZES:
abort(400, description="nur 10 (VGA) oder 11 (SVGA)")
host = urlparse(CAMERA_URL).hostname
if not host:
abort(500, description="CAMERA_URL ohne gueltigen Host")
# Steuer-Endpoint liegt auf Port 80 (Stream laeuft separat auf :81).
ctrl_url = f"http://{host}/control?var=framesize&val={val}"
try:
r = requests.get(ctrl_url, timeout=5)
r.raise_for_status()
except requests.RequestException as exc:
print(f"[cam] framesize set failed: {exc}", flush=True)
return jsonify({"ok": False, "error": str(exc)}), 502
print(f"[cam] framesize -> {FRAMESIZES[val]}", flush=True)
return jsonify({"ok": True, "val": val, "label": FRAMESIZES[val]})
@app.route("/api/reset_count", methods=["POST"])
def reset_count():
data = request.get_json(silent=True) or {}