Raspberry Pi: MJPEG Streaming Web Server (Picamera2)
IoT HardwaresNetworkingProgrammingRaspberry PiTutorials/DIY

Raspberry Pi: MJPEG Streaming Web Server (Picamera2)

Introduction

The Raspberry Pi is one of the most versatile single-board computers for embedded and IoT projects. With its onboard camera support, it has become a go-to device for surveillance systems, robotics, and smart home monitoring.

In this article, we’ll explore how to create an MJPEG (Motion JPEG) streaming web server using Picamera2 — the latest camera library for Raspberry Pi OS, replacing the legacy Picamera. This setup allows you to stream live video over your local network using a lightweight Flask-based web server.

What is MJPEG Streaming?

MJPEG (Motion JPEG) is a video compression format where each frame of a video stream is a standalone JPEG image. It’s widely used in embedded systems and IP cameras because it offers:

  • Low latency streaming
  • Simplicity (no complex codecs like H.264)
  • Browser compatibility (viewable directly via HTML <img> or <video> tags)
  • Ease of implementation using Python and HTTP

While MJPEG streams consume more bandwidth compared to compressed video formats, it’s ideal for local real-time applications where simplicity and speed matter more than compression.

Read this: Best Operating System for Raspberry Pi 2026

Understanding Picamera2

Picamera2 is the modern camera library developed by the Raspberry Pi team, designed to replace the deprecated Picamera module.
It’s built on libcamera, the open-source Linux camera stack, and offers better performance, more control, and compatibility with recent Raspberry Pi OS versions.

Key Features of Picamera2

  • Based on libcamera, offering improved driver support.
  • Provides Python API for image capture and video streaming.
  • Supports camera tuning, image effects, and high resolutions.
  • Integrates with Flask, OpenCV, and NumPy for AI/vision projects.

Hardware and Software Requirements

Hardware:

  • Raspberry Pi 4 / 5 (or Pi 3B+)
  • Raspberry Pi Camera Module (v2, HQ, or compatible)
  • MicroSD card (16GB+)
  • Network connection (Ethernet or Wi-Fi)

Software:

  • Raspberry Pi OS (Bullseye or newer)
  • Python 3.9+
  • Picamera2 library
  • Flask (for web server)

Step 1: Update and Install Dependencies

Before starting, make sure your Raspberry Pi system is up-to-date.

sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip python3-picamera2 libcamera-apps -y

You’ll also need Flask for serving the web page:

pip3 install flask

Step 2: Enable the Camera

Ensure that your camera interface is enabled in the Raspberry Pi configuration.

sudo raspi-config

Navigate to:

Interface Options → Camera → Enable

Reboot your Raspberry Pi after enabling.

Step 3: Test the Camera

Run the following command to verify that the camera is working:

libcamera-still -o test.jpg

If you see an image saved successfully, your camera setup is complete.

Step 4: Create the MJPEG Streaming Server Script

Create a new Python file, e.g., mjpeg_stream.py.

nano mjpeg_stream.py

Paste the following code:

from flask import Flask, Response, render_template_string
from picamera2 import Picamera2
import io
import time
from PIL import Image

app = Flask(__name__)

picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={"size": (640, 480)}))
picam2.start()

# HTML Template
HTML_PAGE = """
<html>
<head><title>Raspberry Pi MJPEG Stream</title></head>
<body>
<h1>📷 Live Stream from Raspberry Pi</h1>
<img src="/video_feed" width="640" height="480">
</body>
</html>
"""

def generate_frames():
    while True:
        frame = picam2.capture_array()
        img = Image.fromarray(frame)
        buffer = io.BytesIO()
        img.save(buffer, format='JPEG')
        frame_bytes = buffer.getvalue()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')

@app.route('/')
def index():
    return render_template_string(HTML_PAGE)

@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, threaded=True)

Save and exit the file.

Step 5: Run the Streaming Server

Execute the script:

python3 mjpeg_stream.py

If everything is set up correctly, you should see:

* Running on http://0.0.0.0:5000/

Open a browser on your PC or phone and visit:

http://<raspberrypi_ip>:5000

You’ll see a live MJPEG video stream directly from your Raspberry Pi camera!

Step 6: Optimize the Stream

To improve performance and reduce CPU load:

  • Lower the resolution (e.g., 320×240)
  • Use threaded=True in Flask
  • Adjust the frame rate using Picamera2 configuration:
picam2.configure(picam2.create_video_configuration(main={"size": (320, 240)}, controls={"FrameDurationLimits": (33333, 33333)}))

Step 7: Auto-Start the Stream on Boot

To run your MJPEG stream automatically at startup, create a systemd service:

sudo nano /etc/systemd/system/mjpeg_stream.service

Add the following:

[Unit]
Description=Raspberry Pi MJPEG Streaming Service
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/mjpeg_stream.py
WorkingDirectory=/home/pi
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

Then enable and start the service:

sudo systemctl enable mjpeg_stream.service
sudo systemctl start mjpeg_stream.service

Use Cases of Raspberry Pi MJPEG Streaming

  1. Home Surveillance Camera – Live video streaming over LAN/WAN.
  2. IoT Monitoring Dashboard – Integrate stream with Flask/Node-RED dashboards.
  3. Robotics Vision System – Stream camera feed from a mobile robot.
  4. AI and Computer Vision Projects – Combine with OpenCV for real-time detection.
  5. Educational Labs – Demonstrate video processing and networking concepts.

Advantages of Using Picamera2 over Legacy Picamera

FeaturePicamera (Old)Picamera2 (New)
BackendMMALLibcamera
Supported OSBuster or earlierBullseye and newer
PerformanceModerateHigh
API ControlLimitedExtensive (tuning, image processing)
Future SupportDeprecatedActively maintained

Troubleshooting

IssuePossible CauseSolution
No image streamCamera not enabledUse raspi-config
Flask app crashesMissing dependenciesRun pip3 install flask pillow
Laggy videoHigh resolutionLower frame size
Port conflictAnother service on port 5000Change Flask port

Future Possibilities

In 2026 and beyond, the Raspberry Pi 5 and new camera modules will offer higher resolutions and hardware-accelerated video streaming. Future versions of Picamera2 may support:

  • H.264/H.265 encoding
  • WebRTC low-latency streaming
  • Edge AI video analytics integration with TensorFlow Lite

Final Thoughts

Building an MJPEG streaming web server using Picamera2 is a rewarding project for both beginners and IoT developers.
It demonstrates how easily a Raspberry Pi can transform into a real-time streaming device — useful in smart surveillance, robotics, and AI vision systems.

With Picamera2, streaming performance is smoother, code is cleaner, and future compatibility is ensured for upcoming Raspberry Pi boards.

Harshvardhan Mishra

Hi, I'm Harshvardhan Mishra. Tech enthusiast and IT professional with a B.Tech in IT, PG Diploma in IoT from CDAC, and 6 years of industry experience. Founder of HVM Smart Solutions, blending technology for real-world solutions. As a passionate technical author, I simplify complex concepts for diverse audiences. Let's connect and explore the tech world together! If you want to help support me on my journey, consider sharing my articles, or Buy me a Coffee! Thank you for reading my blog! Happy learning! Linkedin

Leave a Reply

Your email address will not be published. Required fields are marked *