Recently I had to set up a Raspberry Pi is camera to use as a monitoring device for my printer.
I found that pretty much all the online information was outdated and had no end trouble getting it to work on the current version of Pi OS (Bullseye Bookworm).
The entire camera and video handling system has changed over the years.
So I decided to document what worked for me.
In the end it was relatively easy (once you knew the correct steps0
I must first point out I know bugger all about Linux.
All this work is taken from bits and pieces I found on various sites and cobbled together, so my apologies for not crediting the original author(s)
NOTE: These instructions were done using a Raspberry Pi 4 running Bullseye Bookworm 64 bit and an official Pi camera
Also if you're running RRF in SBC mode, you don't need to do this as I believe it has a built in camera setup.
The first step is to install the OS using the Pi Imager
https://www.raspberrypi.com/software/
When prompted, choose your user name, password and Wifi details.
NOTE: The current version no longer uses the default user pi and password raspberry
when you get to this point, click on "edit settings"
Enable SSH so that you can connect to the Pi via PUTTY rather than always needing a monitor and keyboard.
If you installed a Pi OS that has a desktop you can use the inbuilt command line terminal for all the steps listed below.
Then click on YES to apply the settings.
Once the image has been loaded onto the SD card, insert the card in your Pi and start it up.
Start Putty (or some other terminal) and SSH into the Pi
If you used the default settings, you should be able to go to
raspberrypi.local
You should see something like this
You may get any updates/upgrade by using these commands
sudo apt update
sudo apt upgrade
sudo apt install
Change directory
cd /usr/local/bin/
Open a text edior
sudo nano streamVideo.py
Paste in the following code
#!/usr/bin/python3
# This is the same as mjpeg_server.py, but uses the h/w MJPEG encoder.
import io
import logging
import socketserver
from http import server
from threading import Condition
from picamera2 import Picamera2
from picamera2.encoders import MJPEGEncoder
from picamera2.outputs import FileOutput
PAGE = """\
<html>
<head>
<title>3D Printer Camera</title>
</head>
<body>
<img src="stream.mjpg" width="800" height="600" />
</body>
</html>
"""
class StreamingOutput(io.BufferedIOBase):
def __init__(self):
self.frame = None
self.condition = Condition()
def write(self, buf):
with self.condition:
self.frame = buf
self.condition.notify_all()
class StreamingHandler(server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.send_response(301)
self.send_header('Location', '/index.html')
self.end_headers()
elif self.path == '/index.html':
content = PAGE.encode('utf-8')
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.send_header('Content-Length', len(content))
self.end_headers()
self.wfile.write(content)
elif self.path == '/stream.mjpg':
self.send_response(200)
self.send_header('Age', 0)
self.send_header('Cache-Control', 'no-cache, private')
self.send_header('Pragma', 'no-cache')
self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME')
self.end_headers()
try:
while True:
with output.condition:
output.condition.wait()
frame = output.frame
self.wfile.write(b'--FRAME\r\n')
self.send_header('Content-Type', 'image/jpeg')
self.send_header('Content-Length', len(frame))
self.end_headers()
self.wfile.write(frame)
self.wfile.write(b'\r\n')
except Exception as e:
logging.warning(
'Removed streaming client %s: %s',
self.client_address, str(e))
else:
self.send_error(404)
self.end_headers()
class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer):
allow_reuse_address = True
daemon_threads = True
picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={"size": (640, 480)}))
output = StreamingOutput()
picam2.start_recording(MJPEGEncoder(), FileOutput(output))
try:
address = ('', 8888)
server = StreamingServer(address, StreamingHandler)
server.serve_forever()
finally:
picam2.stop_recording()
Press CTRL + X to exit and choose Y to save file
change directory
cd /etc/systemd/system
Open the text editor to create a system service file
sudo nano streamVideo.service
Paste in the following code
[Unit]
Description=A script for straming video to http
After=syslog.target network.target
[Service]
WorkingDirectory=/usr/local/bin/
ExecStart=/usr/bin/python3 /usr/local/bin/streamVideo.py
Restart=always
RestartSec=120
[Install]
WantedBy=multi-user.target
PRess CTRL + X
press Y and enter to save
Enter the following to reload the daemon
sudo systemctl daemon-reload
Enable the service
sudo systemctl enable streamVideo.service
You should see something like
Created symlink /etc/systemd/system/multi-user.target.wants/streamVideo.service ā /etc/systemd/system/streamVideo.service.
Restart the Pi
sudo shutdown -r now
After the Pi has rebooted, you should be able to access the stream by going to the following URL in your browser
http://raspberrypi.local:8888/index.html
In DWC you need to enter this URL on order to get the stream
http://raspberrypi.local:8888/stream.mjpg
Your video stream should now be visible in the Webcam tab
I hope this saves someone some frustration.