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
- Home Surveillance Camera – Live video streaming over LAN/WAN.
- IoT Monitoring Dashboard – Integrate stream with Flask/Node-RED dashboards.
- Robotics Vision System – Stream camera feed from a mobile robot.
- AI and Computer Vision Projects – Combine with OpenCV for real-time detection.
- Educational Labs – Demonstrate video processing and networking concepts.
Advantages of Using Picamera2 over Legacy Picamera
| Feature | Picamera (Old) | Picamera2 (New) |
|---|---|---|
| Backend | MMAL | Libcamera |
| Supported OS | Buster or earlier | Bullseye and newer |
| Performance | Moderate | High |
| API Control | Limited | Extensive (tuning, image processing) |
| Future Support | Deprecated | Actively maintained |
Troubleshooting
| Issue | Possible Cause | Solution |
|---|---|---|
| No image stream | Camera not enabled | Use raspi-config |
| Flask app crashes | Missing dependencies | Run pip3 install flask pillow |
| Laggy video | High resolution | Lower frame size |
| Port conflict | Another service on port 5000 | Change 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.
