I’m a fan of animated GIFs, and one of my favorite features of UMW’s Convergence Center is it’s “Media Wall,” a large, multi-screen display in the main area of the second floor. It’s a cool place for looping, ambient visual art, so it’s perfect for animated GIFs. Last year, my rendition of Cory Arcangel’s Super Mario Cloudz held the honored position for a few weeks, and more recently, a loop of GIFs by DKC tutors has been on constant repeat.

Over the summer, those tutors, led by Martha Burtis took some incoming students through a workshop in GIFs, the outcome of which is the collection you can see at GIFing.net. The goal was always to take those student-produced GIFs from GIFfing.net and display them on the media wall, but for various reasons, that proved difficult to accomplish consistently. I was interested in the problem, and so as a TTI Fellow, I took at as one of my tasks to try and find a workflow to get those GIFs submitted to GIFfing.net up to the wall. I don’t have a full solution yet, but I wanted to share my work in progress.

One thing we figured out is, GIFs that are the right size for the wall (1920 x 1080) take up a lot of memory, so loading them in a web browser — even on the relatively powerful Mac that displays the wall — will inevitable cause larger GIFs to stutter as the load or even freeze. Before he left, Andy had worked out a way to display the smaller set of 15 or so GIFs using Reveal.js to rotate through the slides, but in addition to the occasional slow loading GIF, after running for a few hours, the javascript in Reveal.js would cause a memory leak that would lock down the computer.

So eventually what I figured out was that websites that routinely display GIFs — Imgur, Gfycat, Giphy, Twitter, etc. — aren’t actually loading animated GIFs most of the time. Instead, they’re using the HTML5 <video> tag to load a looping MP4 video. After a visit to W3Schools I tried a few test MP4’s and hey presto, it’s way faster. Not only are MP4’s a fraction of the size, they don’t start playing back until they’re fully loaded, so no stutter.

I set up a dead simple PHP script that loads a random MP4 from a directory, and let it run. It’s quite simple, so here it is in its entirety.

<!DOCTYPE html>
<html>
<head>
<style>
body {margin:0;padding:0; background-color: black}
</style>
 <meta http-equiv="refresh" content="10" /> 
<body>
<?php
$dir    = './vid';
$files = scandir($dir);
$count = count($files);
$seed =  rand(2,count($files) - 1);
?>
<video width="1920" height="1080" autoplay loop>
<source src="vid/<?php echo $files[$seed]?>" type="video/mp4">
Your browser does not support the video tag.
</video>
<script type="text/javascript">
console.log("ok");
setTimeout(function(){
       console.log("it was me");
   window.location.reload(1);

}, 8000);
</script>
</body>
</html>

I mean, it’s hardly even a “script”, since it just reads the /vid directory and loads one of the files into the <source> element of the <video> tag. The only odd thing you may notice is that it includes two methods for refreshing the page (which re-runs the selection script). Initially, I was just using the <meta http-equiv="refresh"> method to refresh the page. This worked for a while, but occasionally, and for reasons that I never figured out, the web page would get stuck waiting for the server to respond, so the same GIF would loop for maybe a minute or two. It always cleared eventually, but some of these GIFs are not the kind of thing you want to see over and over again for that long.

So I tried using the javascript location.reload() method, tied to a setTimeout function, and for whatever reason, it seems to work fine without dragging. I set the javascript to 8 seconds, and the <meta> to 10 seconds, just as a fallback. I can’t tell if that fallback ever actually happens, but basically it seems to be working so I’m reluctant to mess with it. At least, it was working when I left DTLT today, so if it’s still rotating smoothly tomorrow, I’ll feel pretty good about it. You can see it in action for yourself.

Having figured out the randomized rotation method, the only challenge remaining was to convert all those GIFs to MP4s. Callie was a great help in collecting all 233 student-produced GIFs from GIFfing.net; thanks, Callie! To convert them, I tried a few Mac Apps, but none of those would handle batch conversions. I tried some commandline techniques with ffmpeg and imagemagick, but the results were always poor or didn’t work at all. The only viable solution was to use CloudConvert, but the problem there is that they limit users to 25 CPU minutes per day. This would get me through about 20 GIFs before hitting my daily limit.

Fortunately, as I discovered, CloudConvert doesn’t seem to know about or mind the “infinite GMail trick” (add a “+” and them arbitrary text after your email address name, like “zach.whalen+anything@gmail.com” and it will A) still work and B) usually look like a unique email address to web sites that require an email when you sign up), so with a handful of accounts like zach.whalen+cca, …+ccb, …+ccc, etc., I eventually converted all 233 GIFs.

They’re now all looping at endlessly and randomly in a temporary URL, so feel free to check it out and let me know if you have any suggestions or see any problems.

  • Paul Tuohy

    Fascinating discovery, Zach. I will have to experiment with .mp4 loops now. I’m not much of a coder but the simple application of this code make me want to learn. The GIF wall is dependent on broadband speeds. It’s cropped by my screen size as the display isn’t responsive. I’m streaming it to my Chromecast and it’s very ambient and fluid; like a digital fire of cultural tableaus. I would love to see how it looks as a “MEDIA WALL”. I’m a media student from UOW, I’ll let my lecturers know about this.