How To Make a Simple Time-lapse IP Web Camera Using a Raspberry Pi

How To Make a Simple Time-lapse IP Web Camera Using a Raspberry Pi

When it comes to capturing time-lapse videos, there are numerous off-the-shelf solutions and libraries out there. For last year’s FedEx Day project, I decided to implement a minimalist solution on a Raspberry Pi using only the default image capture API that ships with Raspbian (raspistill), the built-in UNIX task-scheduler (cron), a video conversion utility (avconv), and a lightweight web server (lighttpd).

  1. Set up your Raspberry Pi with the latest version of Raspbian by burning the image to an SD card.
  2. Connect the camera and power on the Pi. Connect to your Wi-Fi or wired network, and open a terminal session, either via SSH or directly on the Pi.
  3. (Optional) Set up a static IP address. This will let you find your server in the same place every time. If you're feeling fancy, you can even set up a DNS server to resolve a URL (e.g. myraspitimelapse.local) to this IP address.
  4. Install libav, which contains avconv. This is the tool we will use to create a video from the captured stills:
     sudo apt-get install libav-tools
  5. Install lighttpd. This will let you view your time-lapse video via a web browser:
     sudo apt-get install lighttpd
  6. Create a basic web page containing the time-lapse video and save it in the directory where lighttp will know to serve it. The most straightforward way is to use the built-in text editor nano:
     sudo nano /var/www/html/index.html
    Then copy in the following HTML, which tells the browser to automatically play the video on loop (the muted attribute is required for some browsers to autoplay):
     <html> <head> <title>My Timelapse</title> </head> <body> <video autoplay loop muted> <source src="timelapse.mp4" type="video/mp4"> </video> </body> </html> 
  7. To create the video, we'll use a simple shell script. Open a new file using nano as before:
     sudo nano /home/pi/timelapse/
    and paste in the following script, which saves a new still photo and generates a video file from all the existing stills every time it runs. It takes an input argument that specifies the number of seconds for the video duration.
     #!/bin/bash # check current time and only take pictures during daylight hours (5am to 7pm) if (( `date +%H` > 5 && `date +%H` < 19 )); then # find the total number of images $n n=1 while [ -f /home/pi/timelapse/stills/img$n.jpg ] do n=$[$n+1] done # take a new picture raspistill -w 640 -h 480 -o /home/pi/timelapse/stills/img$n.jpg # input arg $1 specifies target duration of timelapse video let framerate=$n/$1==0?1:$n/$1 # combine all images in directory into a video sudo avconv -r $framerate -i /home/pi/timelapse/stills/img%d.jpg /var/www/html/timelapse.mp4 -y fi 
  8. Next, change the file permissions so that the script can be executed:
     sudo chmod +x /home/pi/timelapse/
    You should now be able to run your script as:
     /home/pi/timelapse/ 5
    and see the timelapse.mp4 file get created in the directory. Enter the Pi's IP address into your browser, and you should be able to play the 5-second long video. For now, it won't be too exciting, since it will just be a single frame.
  9. Finally, set up the cron job that will trigger shell script. Open the cron table file:
     crontab -e
    Add the following line to the end of the file:
     0 * * * * /home/pi/timelapse/ 30 > /home/pi/timelapse/timelapse.log
    This runs the shell script once per minute, and the input argument of 30 means that the video will be 30 seconds long. The > symbol redirects any errors to the specified log file. You can, of course, use other time intervals as well, and this handy website helps explain the syntax, which can be a little confusing.
  10. And that's it! You can change all the parameters as needed, and you can even try making some tweaks to the script. For example, maybe you want the time-lapse video to show each frame for a set amount of time rather than keeping a fixed duration for the whole video, in which case you can get rid of the input argument and simply set the framerate to a constant.

Learn more about DMC's embedded design expertise


There are currently no comments, be the first to post one.

Post a comment

Name (required)

Email (required)

Enter the code shown above:

Related Blog Posts