Web Preview API

MJPEG streaming helpers - serve live JPEG frames over HTTP.

MjpegStream is a thread-safe latest-frame holder (slow clients simply miss frames instead of building latency); mjpeg_wsgi_app mounts it into any WSGI server (flask/waitress/gunicorn); MjpegServer is a zero-dependency standalone HTTP server for apps that do not run a web framework.

Pair with AppClient.register_web_url() so the platform web console can reach the app container’s MJPEG page.

Example (flask):

source = MjpegStream() app = Flask(__name__) app.route(“/video”)(mjpeg_wsgi_app(source, fps=15)) # push frames from a worker: source.push_frame(frame)

Example (standalone):

server = MjpegServer(port=8080, source=source) server.start() … server.stop()

class neoruntime_ipc_sdk.web.MjpegStream[source]

Bases: object

Thread-safe holder of the most recent JPEG frame.

__init__()[source]
push_jpeg(data)[source]

Publish an already-encoded JPEG frame (bytes).

push_frame(frame, quality=85)[source]

Encode a Frame to JPEG and publish it.

latest()[source]

Most recent JPEG bytes, or None before the first push.

latest_seq()[source]

Monotonic push counter (used with wait_new).

wait_new(after_seq, timeout=1.0)[source]

Block until a frame newer than after_seq arrives (or timeout).

neoruntime_ipc_sdk.web.mjpeg_wsgi_app(source, fps=15)[source]

Build a WSGI callable serving the stream as multipart/x-mixed-replace.

class neoruntime_ipc_sdk.web.MjpegServer(port=8080, host='0.0.0.0', source=None, path='/', fps=15)[source]

Bases: object

Standalone threaded HTTP server exposing one MJPEG stream.

__init__(port=8080, host='0.0.0.0', source=None, path='/', fps=15)[source]
property port: int

Actual bound port (useful when constructed with port=0).

start()[source]

Bind and start serving in a daemon thread.

stop()[source]

Stop serving and close the listening socket (idempotent).

MjpegServer

class neoruntime_ipc_sdk.MjpegServer(port=8080, host='0.0.0.0', source=None, path='/', fps=15)[source]

Bases: object

Standalone threaded HTTP server exposing one MJPEG stream.

__init__(port=8080, host='0.0.0.0', source=None, path='/', fps=15)[source]
property port: int

Actual bound port (useful when constructed with port=0).

start()[source]

Bind and start serving in a daemon thread.

stop()[source]

Stop serving and close the listening socket (idempotent).

MjpegStream

class neoruntime_ipc_sdk.MjpegStream[source]

Thread-safe holder of the most recent JPEG frame.

__init__()[source]
push_jpeg(data)[source]

Publish an already-encoded JPEG frame (bytes).

push_frame(frame, quality=85)[source]

Encode a Frame to JPEG and publish it.

latest()[source]

Most recent JPEG bytes, or None before the first push.

latest_seq()[source]

Monotonic push counter (used with wait_new).

wait_new(after_seq, timeout=1.0)[source]

Block until a frame newer than after_seq arrives (or timeout).

mjpeg_wsgi_app

neoruntime_ipc_sdk.mjpeg_wsgi_app(source, fps=15)[source]

Build a WSGI callable serving the stream as multipart/x-mixed-replace.

Usage Examples

Standalone MJPEG preview server

from neoruntime_ipc_sdk import FdMediaClient, MjpegServer, MjpegStream

media = FdMediaClient()
stream = MjpegStream()

# Threaded HTTP server; open http://<ip>:8080/ in a browser
server = MjpegServer(port=8080, source=stream, fps=15)
server.start()

for frame in media.subscribe("main"):
    stream.push_frame(frame, quality=85)

server.stop()

Push an existing JPEG

# Push JPEGs the app has already encoded
import cv2

ok, jpeg = cv2.imencode(".jpg", annotated)
if ok:
    stream.push_jpeg(jpeg.tobytes())

Inside a WSGI app (Flask / stdlib)

from wsgiref.simple_server import make_server
from neoruntime_ipc_sdk import MjpegStream, mjpeg_wsgi_app

stream = MjpegStream()
app = mjpeg_wsgi_app(stream, fps=15)

make_server("0.0.0.0", 8080, app).serve_forever()

Low-latency latest-frame reads

# latest / wait_new suit custom push logic
seq = stream.latest_seq()
data = stream.latest()          # bytes | None
newer = stream.wait_new(seq, timeout=1.0)
if newer is not None:
    send_to_client(newer)