Skip to main content

MJPEG Streaming Tools

Project description

MJPEG Streaming Utilities for Python 3.x

This 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 with mjpg_streamer.

Installation

pip3 install py-mjpeg

Client API

The library provides a simple threaded streaming client in the file mjpeg/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:

from mjpeg.client import MJPEGClient

url='http://example.com:8080/?action=stream'

# Create a new client thread
client = MJPEGClient(url)

# Allocate memory buffers for frames
bufs = client.request_buffers(65536, 50)
for b in bufs:
    client.enqueue_buffer(b)
    
# Start the client in a background thread
client.start()

To obtain frame data, the application creates a list of memory buffers via client.request_buffers. Each buffer holds exactly one JPEG frame. The application then requests the buffers to be filled by calling client.enqueue_buffer. Once a buffer is enqueued, the application must no longer touch it.

To received finished frames, the application calls client.dequeue_buffer() repeatedly:

while True:
    buf = client.dequeue_buffer()
    <do some work>
    client.enqueue_buffer(buf)

The call to dequeue_buffer is blocking. Each buffer object provides the following attributes:

  • length: The total number of bytes that can fit into the data portion of the buffer
  • used: The number of bytes occupied by frame data in this buffer
  • timestamp: The timestamp of the first byte within this buffers (obtained via time.time())
  • sequence: Frame's sequence number
  • data: Thea actual frame data

You 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 called print_stats which 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    : 0

Server API

The file mjpeg/server.py provides 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:

from Flask import Flask, Response
from mjpeg.server import MJPEGResponse

def relay():
    while True:
        buf = client.dequeue_buffer()
        yield memoryview(buf.data)[:buf.used]
        client.enqueue_buffer(buf)

@app.route('/')
def stream():
    return MJPEGResponse(relay())

if __name__ == '__main__':
    app = Flask(__name__)
    app.run(host='0.0.0.0', port=8080)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py-mjpeg-1.0.1.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

py_mjpeg-1.0.1-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file py-mjpeg-1.0.1.tar.gz.

File metadata

  • Download URL: py-mjpeg-1.0.1.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.14

File hashes

Hashes for py-mjpeg-1.0.1.tar.gz
Algorithm Hash digest
SHA256 037474d24e4a5eb17be3999a271369263e71ff058d8730f6cdd3aa629a756cef
MD5 0a652a53e1e488bc4d86e5afd50b27c2
BLAKE2b-256 51acb6290270824da9f6bf0b1b58a056bddb0ba6b592af827988f7eb108aefba

See more details on using hashes here.

File details

Details for the file py_mjpeg-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: py_mjpeg-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.14

File hashes

Hashes for py_mjpeg-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3ee431681858aa143e1d7866612bc91e00bb465d009a048cc1bb839addf1e1bc
MD5 dc3cfc2560e7324e6ba36042f2980ab7
BLAKE2b-256 f23555b6843a53c9c80209d6aff5154cbe277c5b51490c2455a6de39c0176aba

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page