Real time updating slideshow with webcam photos

I recently hosted a Halloween party and I thought it would be a cool idea to have my Raspberry Pi set up to take photos every few seconds and display them in some sort of slideshow. After a few hours of tinkering with my Raspberry Pi and Camera Module (technically the Pi Noir module), I ended up breaking the camera by sticking it too violently to a mount with Blu-tac. Oops. Not to worry though – I fished out a decent USB webcam and hooked it up to my laptop instead. I didn’t get to use my Raspberry Pi in a nerdy way, but this still did the job.

On the laptop I ran standard webcam software (Cheese) which saved the photos into a specified directory (/home/sean/Pictures/Webcam/). I then ran a cron job every five minutes to synchronise these photos with my web server. In the crontab, I specified a line:

# m h  dom mon dow   command
*/5 * * * * /home/sean/scripts/sync-photos.sh

And in /home/sean/scripts/sync-photos.sh I made an executable script with the following contents:

#!/bin/bash

cd /home/sean/Pictures/Webcam/
rsync *.jpg user@example.com:/path/to/web/directory/halloween/

I had already setup my laptop user account with an SSH key for the server, meaning the rsync command would not ask for a password. This can be done quickly on Ubuntu by doing something like this (but you should Google for a proper guide if you’re unsure):

~$ cd ~/.ssh
~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): <filename here>
Enter passphrase (empty for no passphrase): <password here - this can be blank>
Enter same passphrase again: <password again, or blank>
The key fingerprint is:
a1:a3:32:ff:24:dc:ff:21:10:44:0e:ed:95:c2:ac:e3 user@hostname
The key's randomart image is:
+--[ RSA 2048]----+
<random art>
+-----------------+
~$ ssh-add -i <filename here>

So now, anyone taking a photo with the webcam would have their photo uploaded to my server. So far, so good. I still needed some way of displaying the photos. It turns out that there don’t seem to be very many decent, free and open source slideshow scripts which work in a browser and update their slideshow images periodically. Since the server would potentially receive a bunch of new photos every five minutes, I couldn’t be hitting refresh all night.

I ended up using a nice, simple slideshow script called slides.js. It uses jQuery, a really awesome Javascript library which makes Javascript a bearable programming language. I then crafted a bit of AJAX to grab the directory index page. By default, Apache web server will list all files in a directory if there doesn’t exist a file called index.html, index.php or similar. Index pages are predictable structure – they use simple HTML lists to display a link to each file – so it’s easy to grab out the relevant data with jQuery.

Finally, I had to find a way to update the slideshow periodically. This was not done with Javascript, but rather a rudimentary piece of HTML in the page’s header which tells the user’s browser to refresh every X seconds. I set this to fifteen minutes.

Here is the full slideshow script, which sits in the same web-accessible directory as the images on the server. I also added a piece of code to shuffle the images found in the directory, just to mix things up a bit!

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="refresh" content="900">
    <script src="jquery.js"></script>
    <script src="jquery.slides.min.js"></script>
    <style>
      #slides {
      /* Prevents slides from flashing */
	display:none;
      /* Sets width of photos to fit the screen (in my case, 1750px) */
	width: 1750px;
      }
    </style>
    <script>
      function shuffleArray(array) {
	for (var i = array.length - 1; i > 0; i--) {
	  var j = Math.floor(Math.random() * (i + 1));
	  var temp = array[i];
	  array[i] = array[j];
	  array[j] = temp;
	}
	
	return array;
      }

      function getImages() {
	var images = [];

	$.ajax({
	  url: "http://example.com/path/to/images/",
	  success: function(data){
	    $(data).find("td > a").each(function(){
		var name = $(this).attr("href");

		if (name.slice(-4) == '.jpg') {
	            images.push(name);
		}
	    });

	    // randomise
	    images = shuffleArray(images);

	    var imgstr = "";

	    for (var i = 0; i < images.length; i++) {
	      imgstr += "<img src=\"" + images[i] + "\">";
	    }

	    $('#slides').html(imgstr);

	    $(function(){
	      $("#slides").slidesjs({
		//width: 200,
		//height: 200,
		play: {
		  active: true,
		  effect: "slide",
		  interval: 5000,
		  auto: true,
		  swap: true,
		  pauseOnHover: false,
		  restartDelay: 2500
		}
	      });
	    });

	  }
	});
      }
    </script>
  </head>
  <body>
    <div id="slides"></div>
    <script>
      getImages();
    </script>
  </body>
</html>

The above script cannot be saved as index.html, otherwise it won’t be able to get an index page list of the files in the directory! There are ways around this, e.g. with PHP or similar, but as this was just a hack I renamed the file to slideshow.html.

With all of this set up properly, I opened a browser on my TV, pointed it to this script and entered into full screen mode. It displayed a nice slideshow of photos people took of themselves on my laptop, and updated throughout the night with the latest photos. Awesome!

A Handy Tool for Cleaning Up Disorganised Backups

During my recent trip to Germany, I took a whole bunch of photos with my smartphone. While I was out there, I experimented with a different operating system on my phone. Since my regular contacts from home were communicating with me using different channels (email, WhatsApp, etc.), I could afford to screw up my phone and not go completely off the grid.

It’s always a good idea to backup the contents you can’t afford or don’t wish to lose, even if you’re pretty confident you won’t screw up. So, before my experiments I lazily took a copy of my photos from my phone and dumped it on my laptop’s hard drive. Naturally, after each experiment I did not go back and remove my backup.

Now that I’m back, I’ve been slowly migrating the files associated with the last six months of work from my laptop onto my desktop. Today was the turn of the photos, and I found myself with three separate directories full of largely the same photographs, but not the same names. Removing each duplicate manually would be a pain, so I did some searching and found a nifty program called fdupes. Exactly what I needed! It was available via apt-get, which was even better. Here’s how to do it:

  1. Install fdupes. If you use Ubuntu (or Debian), it’s easy:

    ~$ sudo apt-get install fdupes

    If you use something else, have a look in your package manager or compile the source code (available from fdupes’s GitHub page).

  2. Move the folder(s) you want to remove duplicates across into another folder, e.g.:

    ~$ mv CameraBackup ~/tmppics
    ~$ mv CameraBackup2 ~/tmppics

  3. Run fdupes like this (though with the caveat that you should be careful here, since you’re deleting files – you should backup these files while you remove duplicates!):

    ~$ fdupes -rdN tmppics/

This will look for duplicates in each of the directories within tmppics recursively, and remove all instances of duplicates except the first one found. The -r flag tells fdupes to scan folders recursively, rather than just looking at the files in the top level of the directory specified. The -d flag tells fdupes to delete the files it finds. The -N flag tells fdupes not to prompt you before each deletion. The combination of -d and -N behaves in such a way that the first file found in each matched set is preserved, which is the behaviour I want.