Raspberry Pi Live Camera Webpage Feed V1 (Python / Raspberry Pi)

Camera feed is working with a shot of DC Comics' Sinestro!

I’ve had a Raspberry Pi camera module (v1) since spring 2015, but I’ve rarely put it to use. With some spare time on my hands I have decided to see if I can build a camera feed on a webpage.

Before I continue I should point out that if you are interested in using the Pi and Pi camera module as a security feed then motionEye may be the solution you are looking for.

Also Apache or Nginx and a bash script to capture images from the camera at regular intervals may be a better solution, but I wanted to do this in Python and use Flask as I have used it in previous projects and like it.

Full code for this project is on my GitHub at: https://github.com/geektechdude/python_raspberry_pi_cam_site

Project Directory Layout

The project is split into:

  • camera_flask.py – a Python file containing the Python that controls the camera, Flask and moves the image after it is taken.
  • templates – a folder to hold the HTML template that the render engine calls
  • flask_temp.html – the HTML template that the render engine calls and then fills in with relevant details
  • latest.jpg – the latest photo taken by the camera
  • old_images – a folder containing previous photos taken by the camera
Project directory layout
Project directory layout

Originally I did not use the “latest.jpg” and had Flask calling on the latest photo via it’s name however I then had issues trying to keep the photos organised.

The Code

camera_flask.py

# geektechstuff

# Libraries to import

from flask import Flask, render_template

from picamera import PiCamera

from datetime import datetime

import shutil

import os

app = Flask(__name__,static_url_path='',static_folder='/home/pi/flask_photo/')

def save_photo():

    camera = PiCamera()

    filename = datetime.now().strftime("%H%M%Y%m%d.jpg")

    camera.capture(filename)

    camera.close()

    shutil.copyfile(filename,'/home/pi/flask_photo/latest.jpg')

    new_location = "/home/pi/flask_photo/old_images/"+filename

    shutil.copyfile(filename, new_location)

    if os.path.exists(filename):

        os.remove(filename)

    return()

@app.route('/')

def load_page():

    save_photo()

    time_hour_min = datetime.now().strftime("%H:%M")

    time_date = datetime.now().strftime("%d-%m-%y")

    return render_template("flask_temp.html", time_hour_min=time_hour_min, time_date=time_date)
geektechstuff_pi_cam_3
camera_flask.py contents

camera_flask.py has two functions:

  • save_photo(): Uses the Pi Camera module to take a photo, then saves it using the current system time/date. It then copies that file as latest.jpg and also copies itself (with the original timestamp name) to the /old_images/ directory before deleting the file from the original location. This stops the /flask_photo/ directory from being flooded by photo (jpg) files and allows the HTML to reference the latest.jpg rather than the timestamp name.
  • load_page(): Loads the page and adds a time reference onto the page. I have some ideas of other functionality I want to add at a future date.

flask_temp.html

<!DOCTYPE html>

<head>

<meta http-equiv="refresh" content="30" >

</head>

<title>GeekTechStuff Live Photo</title>

<body>

<p><b>GeekTechStuff</b>

<br>

Current view:<br>

</p>

<img src="latest.jpg" alt="Current View" width="400" height="300">

<p>Taken: {{time_date}} at {{time_hour_min}}</p>

</body>

</html>
geektechstuff_pi_cam_4
Contents of flask_temp.html

flask_temp.html is the HTML template that Flask calls on using the render engine, passing in values for text within the curly braces {{ }}. I admit flask_temp is a little bland at the moment, but I wanted to make sure that the Python and camera were working correctly before adding details to the HTML, or adding CSS to control the styling of the page.

The web page takes a new photo each time it loads (or is fully refreshed), I have added in:

<meta http-equiv="refresh" content="30" >

to make the web page refresh every 30 seconds which updates the image.

Currently I am using the command:

FLASK_APP=camera_flask.py flask run --host=0.0.0.0

to run the webpage, with the host as 0.0.0.0 so that I can access it from other computers on my personal network.

I’m serving up the page from my Pi on port 5000, and my first attempt (which was still using the timestamp method for the image name) worked ok as it showed Sinestro on my desk.

Camera feed is working with a shot of DC Comics' Sinestro!
Camera feed is working with a shot of DC Comics’ Sinestro!

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.