Erster Commit: MJPEG-Relay, Stream-Tool und README

This commit is contained in:
Joachim Hummel committed 2026-10-17 20:22:40 +02:00
commit 2de90feafc
5 files changed
+388

No files matched your search

+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""MJPEG-Stream auslesen.
Beispiele:
python3 webcam.py # Verbindung testen, Frame-Infos ausgeben
python3 webcam.py --snapshot bild.jpg # ein Einzelbild speichern
python3 webcam.py --save frames/ -n 50 # 50 Frames als JPEG speichern
python3 webcam.py --show # Live-Fenster (benötigt opencv-python + numpy)
"""
import argparse
import os
import sys
import time
import requests
URL = "http://192.168.10.82:8080/stream.mjpg"
SOI, EOI = b"\xff\xd8", b"\xff\xd9"
def frames(url, timeout=10):
"""Generator: liefert jedes JPEG-Frame des MJPEG-Streams als bytes."""
with requests.get(url, stream=True, timeout=timeout) as r:
r.raise_for_status()
buf = b""
for chunk in r.iter_content(chunk_size=4096):
buf += chunk
while True:
start = buf.find(SOI)
if start < 0:
buf = b""
break
end = buf.find(EOI, start + 2)
if end < 0:
buf = buf[start:]
break
yield buf[start:end + 2]
buf = buf[end + 2:]
def main():
p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
p.add_argument("--url", default=URL)
p.add_argument("--snapshot", metavar="DATEI", help="ein Frame speichern und beenden")
p.add_argument("--save", metavar="ORDNER", help="Frames in Ordner speichern")
p.add_argument("-n", type=int, default=0, help="nach N Frames beenden (0 = endlos)")
p.add_argument("--show", action="store_true", help="Live-Fenster anzeigen (OpenCV)")
a = p.parse_args()
if a.show:
import cv2
import numpy as np
if a.save:
os.makedirs(a.save, exist_ok=True)
count, t0 = 0, time.time()
try:
for jpg in frames(a.url):
count += 1
if a.snapshot:
with open(a.snapshot, "wb") as f:
f.write(jpg)
print(f"Gespeichert: {a.snapshot} ({len(jpg)} Bytes)")
return
if a.save:
with open(os.path.join(a.save, f"frame_{count:06d}.jpg"), "wb") as f:
f.write(jpg)
if a.show:
img = cv2.imdecode(np.frombuffer(jpg, np.uint8), cv2.IMREAD_COLOR)
cv2.imshow("Webcam", img)
if cv2.waitKey(1) & 0xFF in (ord("q"), 27):
break
fps = count / (time.time() - t0)
print(f"\rFrame {count} {len(jpg)} Bytes {fps:.1f} fps", end="", flush=True)
if a.n and count >= a.n:
break
except KeyboardInterrupt:
pass
except requests.RequestException as e:
sys.exit(f"Verbindungsfehler: {e}")
print()
if __name__ == "__main__":
main()