From 51dd440e6c94752c81b18d609b19fc819f3c81e5 Mon Sep 17 00:00:00 2001 From: igolus Date: Mon, 19 Sep 2022 14:05:53 +0200 Subject: [PATCH] Take a snap example --- RPiCameraPython/takeASnap.html | 157 +++++++++++++++++++++++++++++++++ RPiCameraPython/takeASnap.py | 94 ++++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 RPiCameraPython/takeASnap.html create mode 100644 RPiCameraPython/takeASnap.py diff --git a/RPiCameraPython/takeASnap.html b/RPiCameraPython/takeASnap.html new file mode 100644 index 0000000..dd2e6b1 --- /dev/null +++ b/RPiCameraPython/takeASnap.html @@ -0,0 +1,157 @@ + + + + + picamera MJPEG Take a snap + + +
+

Take snap

+
+ +

+
+
+ +
+ + + + + \ No newline at end of file diff --git a/RPiCameraPython/takeASnap.py b/RPiCameraPython/takeASnap.py new file mode 100644 index 0000000..682473a --- /dev/null +++ b/RPiCameraPython/takeASnap.py @@ -0,0 +1,94 @@ +import io +import picamera +import logging +import socketserver +from threading import Condition +from http import server +import shutil + +with open('takeASnap.html', 'r') as file: + PAGE = file.read() + +class StreamingOutput(object): + def __init__(self): + self.frame = None + self.buffer = io.BytesIO() + self.condition = Condition() + + def write(self, buf): + if buf.startswith(b'\xff\xd8'): + # New frame, copy the existing buffer's content and notify all + # clients it's available + self.buffer.truncate() + with self.condition: + self.frame = self.buffer.getvalue() + self.condition.notify_all() + self.buffer.seek(0) + return self.buffer.write(buf) + +class StreamingHandler(server.BaseHTTPRequestHandler): + def do_GET(self): + if self.path == '/': + self.send_response(301) + self.send_header('Location', '/index.html') + self.end_headers() + elif self.path == '/index.html': + content = PAGE.encode('utf-8') + self.send_response(200) + self.send_header('Content-Type', 'text/html') + self.send_header('Content-Length', len(content)) + self.end_headers() + self.wfile.write(content) + elif self.path.startswith('/lastSnappedImage'): + self.send_response(200) + self.send_header('Content-type', 'image/jpeg') + self.end_headers() + with open('image.jpg', 'rb') as content: + shutil.copyfileobj(content, self.wfile) + elif self.path == '/snap': + print("SNAP !!!") + camera.capture('image.jpg') + self.send_response(200) + self.end_headers() + elif self.path == '/stream.mjpg': + self.send_response(200) + self.send_header('Age', 0) + self.send_header('Cache-Control', 'no-cache, private') + self.send_header('Pragma', 'no-cache') + self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME') + self.end_headers() + try: + while True: + with output.condition: + output.condition.wait() + frame = output.frame + self.wfile.write(b'--FRAME\r\n') + self.send_header('Content-Type', 'image/jpeg') + self.send_header('Content-Length', len(frame)) + self.end_headers() + self.wfile.write(frame) + self.wfile.write(b'\r\n') + except Exception as e: + logging.warning( + 'Removed streaming client %s: %s', + self.client_address, str(e)) + else: + self.send_error(404) + self.end_headers() + +class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer): + allow_reuse_address = True + daemon_threads = True + +# 4 fps = 6 Mbps +#24 fps = 18 Mbps +with picamera.PiCamera(resolution='640x480', framerate=24) as camera: + #camera.rotation = 180 + output = StreamingOutput() + camera.start_recording(output, format='mjpeg') + try: + address = ('', 8000) + server = StreamingServer(address, StreamingHandler) + server.serve_forever() + finally: + camera.stop_recording() \ No newline at end of file