h264streamer.py (2359B)
1 import io 2 import picamerax as picamera 3 import time 4 from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer 5 from wsgiref.simple_server import make_server 6 from ws4py.websocket import WebSocket 7 from ws4py.server.wsgirefserver import WSGIServer, WebSocketWSGIHandler, WebSocketWSGIRequestHandler 8 from ws4py.server.wsgiutils import WebSocketWSGIApplication 9 from threading import Thread, Condition 10 11 12 class FrameBuffer(object): 13 def __init__(self): 14 self.frame = None 15 self.buffer = io.BytesIO() 16 self.condition = Condition() 17 18 def write(self, buf): 19 if buf.startswith(b'\x00\x00\x00\x01'): 20 with self.condition: 21 self.buffer.seek(0) 22 self.buffer.write(buf) 23 self.buffer.truncate() 24 self.frame = self.buffer.getvalue() 25 self.condition.notify_all() 26 27 28 def stream(): 29 with picamera.PiCamera(resolution='1920x816', framerate=25) as camera: 30 broadcasting = True 31 frame_buffer = FrameBuffer() 32 camera.start_recording(frame_buffer, format='h264', profile="baseline") 33 try: 34 WebSocketWSGIHandler.http_version = '1.1' 35 websocketd = make_server('', 9000, server_class=WSGIServer, 36 handler_class=WebSocketWSGIRequestHandler, 37 app=WebSocketWSGIApplication(handler_cls=WebSocket)) 38 websocketd.initialize_websockets_manager() 39 websocketd_thread = Thread(target=websocketd.serve_forever) 40 41 httpd = ThreadingHTTPServer(('', 8000), SimpleHTTPRequestHandler) 42 httpd_thread = Thread(target=httpd.serve_forever) 43 44 try: 45 websocketd_thread.start() 46 httpd_thread.start() 47 while broadcasting: 48 with frame_buffer.condition: 49 frame_buffer.condition.wait() 50 websocketd.manager.broadcast(frame_buffer.frame, binary=True) 51 except KeyboardInterrupt: 52 pass 53 finally: 54 websocketd.shutdown() 55 httpd.shutdown() 56 broadcasting = False 57 raise KeyboardInterrupt 58 except KeyboardInterrupt: 59 pass 60 finally: 61 camera.stop_recording() 62 63 if __name__ == "__main__": 64 stream()