Streaming images from RaspberryPi to an HTML website
We will repeatedly take images on a raspberrypi using the raspistill
command and then stream that.
Step 1: Lets take a picture repeatedly and place it at /tmp/pic.jpg
mkdir /tmp/stream
raspistill -w 640 -h 480 -q 25 -o /tmp/stream/pic.jpg -tl 100 -t 999999 -v -th 0:0:0 &
Step 2: Let’s setup a stream of these images
LD_LIBRARY_PATH=./ ./mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w ./www"
We are using a MJPEG (Motion JPEG) stream by using open sourced software called MJPG-Streamer.
Here is a link which outlines installing it.
It is looking for a file called pic.jpg and every time it changes, it streams the file. Its using an HTTP server as output.
The down side of MJPEG streams is that they are not as efficient as H.264, which greatly improves quality and reduces size by encoding only the differences from one frame to the next. With MJPEG each frame is encoded as an entire JPEG picture.
Step 3: Understand what the streaming server is giving us
We have 2 urls which give us content:
The snapshot url, is returning a content-type
of image/jpeg
. But every-time it’s loaded it will give you the latest image pic.jpg has.
The stream url, is returning a content-type
of multipart/x-mixed-replace
and boundary=boundarydonotcross
. And then it’s response has content type of image/jpeg
where each image is seperated by --boundarydonotcross
.
HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace; boundary=myboundary
--myboundary
Content-Type: image/jpeg
Content-length: 12345
[image 1 encoded jpeg data]
--myboundary
Content-Type: image/jpeg
Content-length: 45678
[image 2 encoded jpeg data]
...
To view
You can include the stream url in an image tag and it will always show the latest image. Or you can include the snapshop url in an image tag and it will show you the image of that time and then you can refresh it to get the latest image.
Summary
Take a bunch of pictures and just return them to the browser with each picture separated by a boundary element. Use raspistill
to take the pictures and then an out of the box too like mjpg-streamer
to build the stream from those images.