How to Build a Very Slow Movie Player for £120 in 2020

Ambient home cinema was the perfect lockdown project

My Very Slow Movie Player in an IKEA frame playing Alfred Hitchcock’s Psycho. Photos courtesy of the author
Bryan Boyer’s original VSMP (link)
  1. Connect to the e-paper screen and install the driver code on the Pi.
  2. 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.
  3. Find some kind of frame to keep it all together.

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.)

The Raspberry Pi and the e-paper Hat hot-glued to the back of an Ikea picture frame. The power comes in through the USB-C connector on the bottom left of the Pi.

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.

  • 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.
sudo raspi-config <-- Don’t forget to turn on SPIgit clone ‘SlowMovie/e-paper/RaspberryPi&JetsonNano/python’sudo python install
Waveshare’s version of Hello World
IOError: [Errno 2] No such file or directory
My version of hello world shows random frames from a two-second snippet of Psycho

Hello world

Now that the screen is connected and working, navigate back to the SlowMovie folder:

cd ~/SlowMovie
  • ffmpeg-python wraps ffmpeg for Python.
  • PIL is the Python Image Library.
sudo pip install ffmpeg-python
# 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):    
.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)
.run(capture_stdout=True, capture_stderr=True)
# Import, initialise and clear the displayfrom waveshare_epd import epd7in5_V2
epd = epd7in5_V2.EPD()
# 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 =“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 working, you can transfer more videos onto the device using SFTP. Simply drop .mp4 files into the /Videos folder.

python -h
python -f 2001.mp4 -d 150 -i 1
sudo nano /etc/profile
cd SlowMoviesudo python

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.

Algorithmic art inspired by Georg Nees

Next steps

Consultant at Fluxx, reformed journalist, hardware designer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store