tarinaretake

git clone https://git.tarina.org/tarinaretake
Log | Files | Refs | README | LICENSE

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()