Package: py-mjpeg
MJPEG Streaming Utilities for Python 3.xThis library provides utility functions for working with MJPEG streams.
MJPEG is a simple streaming protocol running on top of HTTP that is used by many existing webcams.
The library provides a threaded client and a streaming generator for Flask based servers.The library is only compatible with Python 3.x (tested on Python 3.4 and 3.5).
It was tested withmjpg_streamer.Installationpip3installpy-mjpegClient APIThe library provides a simple threaded streaming client in the filemjpeg/client.py.
The client is designed to run in a separate background thread to ensure that it can continue reading from the stream
while the main thread is blocked.
The client automatically reconnects to the server if it gets disconnected.Here is a simple example:frommjpeg.clientimportMJPEGClienturl='http://example.com:8080/?action=stream'# Create a new client threadclient=MJPEGClient(url)# Allocate memory buffers for framesbufs=client.request_buffers(65536,50)forbinbufs:client.enqueue_buffer(b)# Start the client in a background threadclient.start()To obtain frame data, the application creates a list of memory buffers viaclient.request_buffers.
Each buffer holds exactly one JPEG frame.
The application then requests the buffers to be filled by callingclient.enqueue_buffer.
Once a buffer is enqueued, the application must no longer touch it.To received finished frames, the application callsclient.dequeue_buffer()repeatedly:whileTrue:buf=client.dequeue_buffer()<dosomework>client.enqueue_buffer(buf)The call todequeue_bufferis blocking.
Each buffer object provides the following attributes:length: The total number of bytes that can fit into the data portion of the bufferused: The number of bytes occupied by frame data in this buffertimestamp: The timestamp of the first byte within this buffers (obtained via time.time())sequence: Frame's sequence numberdata: Thea actual frame dataYou can use a memory view to obtain frame data from the buffer:data=memoryview(buf.data)[:buf.used]When the client runs out of buffers to store frames, it will continue receiving the stream, but any frame data will be discarded.
If the connection is disconnected or if the client detects a protocol error, it will try to reconnect the stream automatically.
If the client receives a frame that is larger than the destination buffer, the frame will be discarded.The client can be stopped via its stop() method:client.stop()If the client shall be restarted after calling stop() one must create a new instance as threads can only be started once:# Create a new client thread
client = MJPEGClient(url)The client provides a method calledprint_statswhich can be used for debugging:MJPEGClient:
  URL:            : http://example.com:8080/?action=stream
  FPS             : 30
  Buffer overruns : 2
  Reconnects      : 0
  Total frames    : 2984
  Discarded frames: 704
  Buffer queue    : 0Server APIThe filemjpeg/server.pyprovides a generator for Flask that can be used to generate a MJPEG stream from iterator data.Here is a simple "echo" example which just sends any frames received from a client back to the client:fromFlaskimportFlask,Responsefrommjpeg.serverimportMJPEGResponsedefrelay():whileTrue:buf=client.dequeue_buffer()yieldmemoryview(buf.data)[:buf.used]client.enqueue_buffer(buf)@app.route('/')defstream():returnMJPEGResponse(relay())if__name__=='__main__':app=Flask(__name__)app.run(host='0.0.0.0',port=8080)