Raspberry Camera Mjpg Video Streaming Over the Internet

I saw attempts to stream a video from a raspberry pi to your web application running on NodeJS. Most of the ideas used non standard solutions eg sending base64 image strings over WebSockets to a web client.

This is a simple example of how you can create mjpg stream, expose it to the internet from your local raspberry pi and have access to it from anywhere over the internet or use it in your application UI.

The instruction assumes you have nodejs installed and camera set up on you rasperry pi.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Create Local Python Http Server and Capture Video Stream From Your Raspberry

stream.py:

import io
import picamera import logging import socketserver from threading import Condition from http import server PORT = 9090 FRAME_RATE = 24 RESOLUTION = '640x480' class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition()
def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf)
class StreamingHandler(server.BaseHTTPRequestHandler): def do_GET(self): if self.path == '/': 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

with picamera.PiCamera(resolution=RESOLUTION, framerate=FRAME_RATE) as camera: output = StreamingOutput() #Uncomment the next line to change your Pi's Camera rotation (in degrees) #camera.rotation = 90 camera.start_recording(output, format='mjpeg') try: address = ('', PORT) server = StreamingServer(address, StreamingHandler) server.serve_forever() finally: camera.stop_recording()

Step 2: Create Config File for Our JS App

package.json:

{
"name": "mjpeg-video-stream", "version": "1.0.0", "description": "mjpeg video stream", "main": "main.js", "scripts": { "start": "node main.js" }, "author": "givehug", "license": "MIT", "dependencies": { "ngrok": "3.2.5" } }

Step 3: Create Main JS File to Run Application

main.js:

const ngrok = require('ngrok');
const {spawn} = require('child_process');

const stream = spawn('python3', ['./stream.py']);

stream.stdout.once('data', async() => {
const url = await ngrok.connect(9090);
});

Step 4: Run a Program

Thats almost it, run

npm i<br>npm start

Now you have control over your ngrok generated video stream url here

const url = await ngrok.connect(9090);

use it however you prefer. I usually send it to my NodeJS web server in cloud and then to my web application as src to an image element:

<img src="https://user:pwd@c038f6f8.ngrok.io" />


PS:

- generated url will be different every time, you may want to opt in for prepaid static url by ngrok

- you may want to password protect your video stream, here is an example:

const url = await ngrok.connect({<br>    addr: 9090,
    auth: 'user:pwd',
});

- if you do not use NodeJS, you can install standalone ngrok executable directly on your raspberry pi (or look for similar python modules). Run your stream.py script and start ngrok at port 9090:

./ngrok http 9090

then follow the url displayed in the terminal window.

References:

- full source code
- ngrok
- ngrok js
- picamera web streaming

Be the First to Share

    Recommendations

    • CNC Contest

      CNC Contest
    • Make it Move

      Make it Move
    • Teacher Contest

      Teacher Contest

    Discussions