How to Build a Very Slow Movie Player for £120 in 2020
Ambient home cinema was the perfect lockdown project
In December 2018, Bryan Boyer published “Creating a Very Slow Movie Player.” It’s a wonderful essay about light and Brasília and architecture. Boyer describes building an e-paper display that shows films at 24 frames per hour, rather than 24 frames per second. So it would take about a year to play the 142 minutes of 2001: A Space Odyssey.
Every few months since 2018, I’ve thought about Boyer’s essay and visited the e-paper department at Waveshare, a Shenzhen-based electronics retailer.
They now sell a $58 7.5-inch e-paper screen that comes with all the connections for a Raspberry Pi. So I finally bought one, and got it working over a couple of days.
It’s been playing Psycho in the corner of our dining room for the last two months. I set it to run slightly faster than Boyer’s — it refreshes every two minutes, and jumps forward four frames each time. That’s about two minutes of screen time per 24 hours, a little under three months for a 110-minute film.
Psycho is full of visual treats, which reveal themselves very gradually. Some images — Janet Leigh driving — stuck around for weeks, while the shower scene was over in a day and a half.
If you want to build yourself a VSMP, there are four things to do:
- Get the Raspberry Pi working in headless mode without a monitor, so you can upload files and run code.
- Connect to the e-paper screen and install the driver code on the Pi.
- Write some code (or use mine) to extract frames from a movie file, resize and dither those frames, display them on the screen, and keep track of progress through the film.
- Find some kind of frame to keep it all together.
This is a relatively straightforward project. There’s no soldering and no hardcore coding. If you’re at all comfortable using a command line, and you’ve seen Python script before then you’ll be fine.
The e-paper screen, Pi, SD Card, and Ikea frame cost me about £120 (about $153) in total.
IMPORTANT UPDATE APRIL 2021: This project has been evolving since it was originally published, with several excellent contributors working to improve the code. Some of the installation instructions below are now out of date — please check the github repository for the latest installation instructions.
NB: Everything I know about this subject is in this post, so I can’t help you beyond what is written here. If you ask questions on GitHub others may be able to help.
Get started with Raspberry Pi
There are numerous how-to guides that explain how to set up a Raspberry Pi. I bought 2GB Raspberry Pi 4, a power supply, and a NOOBS 64gb SD Card from Pimoroni. NOOBS includes almost all the libraries we’ll use, so it makes life a lot easier. (This guide is useful if you don’t want to buy a NOOBS card.)
To work without a traditional screen, the two main tools are: SSH to control the device through the command line (I used MacOS Terminal) and SFTP to upload files (I used Filezilla).
Once you have SSH running — it can be a faff, instructions are here — you’re in control of the Pi over your home Wi-Fi network. You can move through folders, run applications, edit files, and so on. You’ll need to know basic terminal commands but I don’t think I used much beyond ls (list files), cd (change directory), and nano (a basic text editor, that takes a bit of getting used to).
I also used SFTP to do the heavy lifting — transferring big movie files onto the Pi, and uploading the code I’d written before polishing it with nano.
Connecting the display
The display is shockingly thin, and comes with a flexible PCB cable and a breakout board that plugs straight into the Raspberry Pi. There is a plastic sheet over the screen that you can remove.
- Physically connecting the e-paper display to the Raspberry Pi is simple — just plug it in to the GPIO pins. This is the biggest change since Bryan Boyer’s experience in 2018.
- Turn on SPI on the Raspberry Pi. This is how the Pi communicates with the e-paper screen, so is absolutely critical. It’s a simple thing to do once you’re SSH’d into the Pi: How to enable SPI.
Next, you need to download and install the driver software and my code onto the Pi.
This assumes you’re using a Pi with NOOBS — otherwise, you may have to install or update more tools (Git, Pip, Pil, ffmpeg) yourself.
Use SSH to connect to the Pi then run these commands (start in your home folder) one by one: (NB: you do need the quotes in line two)
NB: Please check the github repository for updated instructions
sudo raspi-config <-- Don’t forget to turn on SPIgit clone https://github.com/TomWhitwell/SlowMovie/cd ‘SlowMovie/e-paper/RaspberryPi&JetsonNano/python’sudo python setup.py install
Now, if everything has worked, you should be able to run this command to see the e-paper display come to life:
python examples/epd_7in5_V2_test.py
If this doesn’t work, check that 1) you turned on SPI earlier and 2) your e-paper display is a 7.5 inch V2.
When SPI isn’t turned on, you get very unhelpful messages like:
IOError: [Errno 2] No such file or directory
When I first tried this, it didn’t work, then worked, then didn’t work. I became convinced there was a hardware problem, that I’d somehow damaged the fragile ribbon cable connecting the display. It was not hardware. It was just that I forgot to turn on SPI, then ran the wrong demo code.
There are switches on the Hat that connects to the screen. Mine are in this position: Display Config: B: Other. Interface Config: 0: 4-Line SPI.
Hello world
Now that the screen is connected and working, navigate back to the SlowMovie folder:
cd ~/SlowMovie
My version of the Slow Movie Player software uses Python with three libraries:
- Ffmpeg is a Swiss Army Knife for video and audio files.
- ffmpeg-python wraps ffmpeg for Python.
- PIL is the Python Image Library.
If you used NOOBs, then ffmpeg and PIL are already installed. Ffmpeg is slightly fiddly to install, but there are plenty of tutorials out there. If you struggle, use NOOBS.
NB: Please check the github repository for updated instructions
To install ffmpeg-python:
sudo pip install ffmpeg-python
Now everything should be in place, so you can run this hello world file (ensure you’re in the SlowMovie folder):
python helloworld.py
This picks a random .mp4 video (there’s a short test.mp4 clip already there). It extracts a random frame, resizes and dithers it, and puts it on the screen. The full code is here, the more interesting bits are here:
# Use ffmpeg to extract a single frame from the .mp4 file, resize it, letterbox it and save it locallydef generate_frame(in_filename, out_filename, time, width, height):
(
ffmpeg
.input(in_filename, ss=time)
.filter('scale', width, height, force_original_aspect_ratio=1)
.filter('pad', width, height, -1, -1)
.output(out_filename, vframes=1)
.overwrite_output()
.run(capture_stdout=True, capture_stderr=True)
)# Import, initialise and clear the displayfrom waveshare_epd import epd7in5_V2
epd = epd7in5_V2.EPD()
epd.init()
epd.Clear()# Check how many frames are in the movieframeCount = int(ffmpeg.probe(inputVid)[‘streams’][0][‘nb_frames’])# Pick a random frameframe = random.randint(0,frameCount)# Convert that frame count to Timecode used by ffmpegmsTimecode = “%dms”%(frame*41.666666)# Open the saved frame in PILpil_im = Image.open(“grab.jpg”)# Convert the image to a 1 bit bitmap (Just zeros and ones)# using Floyd Steinberg ditheringpil_im = pil_im.convert(mode=’1',dither=Image.FLOYDSTEINBERG)# display the imageepd.display(epd.getbuffer(pil_im))
The very slow movie player
Once you have helloworld.py working, you can transfer more videos onto the device using SFTP. Simply drop .mp4 files into the /Videos folder.
Keep an eye on the storage capacity — if you have half-downloaded video files or a completely full SD card you’ll get weird errors.
My rather hacky SlowMovie player is:
python slowmovie.py
Which saves progress through videos so you can turn off the power and continue where you left off.
It has various options which you can see by typing:
python slowmovie.py -h
For example:
python slowmovie.py -f 2001.mp4 -d 150 -i 1
Will play 2001.mp4, updating the screen every 150 seconds, and showing every single frame — 24 frames per hour, instead of 24 frames per second.
The display will update as long as the program is running, and will stop once the ssh session finishes. To start slowmovie.py automatically every time the device is powered up: Instructions are here, but essentially you need edit the user profile:
sudo nano /etc/profile
At the bottom of that file, add these lines, with whatever options you want, save, and exit.
cd SlowMoviesudo python slowmovie.py
Finishing off
The screen is so thin that it can be mounted in a normal Ikea picture frame. I used a frame bought years ago, but it looks like a Ribba. I threw away the glass and spray painted the frame and mounting card black to make the screen stand out better. I hot-glued the Pi to the back of the frame, which really doesn’t work very well. Next, I’m going to take the whole thing to a picture framer to have them do it properly.
Next steps
- There’s a lot to explore in the Waveshare catalog: A much higher resolution version of the screen I used for $140, a slightly bigger one for $170, and a much bigger raw screen for $150.
- PIL seems to only include one dithering algorithm (Floyd-Steinberg) but here are many more to try.
- It would be nice to get the code to read .mp4 files from a USB thumb drive, but I couldn’t get it to work.
- There are many different types of e-paper screen, and some allow partial refresh, which might get around the ugly flashing screen every time the image changes.
- Once you have a small connected ambient display in your home, you find interesting things to do with it. I’d love a version of Christian Marclay’s The Clock for e-paper displays. In Extras, you can find a couple of quick sketches recreating Alison Knowles House Of Dust and Georg Nees Computergrafik (I’ve been reading Mainframe Experimentalism).
Tom Whitwell is managing consultant at Fluxx. He also designs electronics as Music Thing Modular — Human Sized Musical Interfaces and writes lists like “52 Things I Learned in 2019.”