liveBook · Manning

Motion JPEG

As explained in Build Your Own Robot: Using Python, CRICKIT, and Raspberry Pi

Motion JPEG is a video format that represents a video as a continuous sequence of independently encoded JPEG images.

Motion JPEG represents video as a continuous stream of independently encoded JPEG images. In a robot web application, a browser receives those images as a live view of the camera. section 10.4.5

A practical Motion JPEG server performs these steps:

  • Watch a camera image file for changes, polling frequently enough to detect new frames. section 10.4.5
  • Set the response content type to multipart Motion JPEG and define boundaries separating successive images. section 10.4.5
  • Read each new JPEG, write it with its JPEG header and boundary, then flush the response to the browser. section 10.4.5
Listing 10.6 stream_web.py: Streaming video to web applications
#!/usr/bin/env python3
import os
import asyncio
import tornado.web
from watcher import FileWatcher
 
IMG_PATH = os.environ['XDG_RUNTIME_DIR'] + '/robo_stream.jpg'
POLL_DELAY = 1 / 60
CONTENT_TYPE = 'multipart/x-mixed-replace;boundary=image-boundary'
BOUNDARY = b'--image-boundary\r\n'
JPEG_HEADER = b'Content-Type: image/jpeg\r\n\r\n'
 
class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        self.set_header('Content-Type', CONTENT_TYPE)
        watcher = FileWatcher(IMG_PATH)
        while True:
            if watcher.has_changed():
                img_bytes = open(IMG_PATH, 'rb').read()
                self.write(BOUNDARY + JPEG_HEADER + img_bytes)
                self.flush()
            await asyncio.sleep(POLL_DELAY)
 
async def main():
    app = tornado.web.Application([('/', MainHandler)])
    app.listen(9000)
    shutdown_event = asyncio.Event()
    await shutdown_event.wait()
 
asyncio.run(main())

Use the complete Tornado listing to see the image watcher, multipart headers, asynchronous polling loop, and streaming response assembled into one server. section 10.4.5

Live robot-camera view

A robot writes successive camera frames to robo_stream.jpg. A Tornado web server detects changes and streams the JPEGs to a phone or computer on the network, allowing the viewer to see what the robot sees. section 10.0 section 10.4.5

How Build Your Own Robot: Using Python, CRICKIT, and Raspberry Pi covers it

How deep it goes
Defines JPEG sequencing and implements multipart delivery with file watching, polling, and flushing, without detailing codec internals.
Examples
Uses a Tornado server that watches robo_stream.jpg and displays the robot camera on a mobile device.
What it assumes
Assumes a camera image file and Python web-server components; teaches multipart content types, boundaries, and frame delivery.
What you can do after
Build it from scratch with Tornado by polling an image file and emitting multipart JPEG responses to browsers.
How it connects
Connects JPEG images with web browsers, HTTP multipart responses, Tornado, asyncio, filesystem watching, and camera streams.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build Your Own Robot: Using Python, CRICKIT, and Raspberry Pi. The section links point to the parts of the book it draws on.