Tibor Udvari

Raspberry Pi Zero Video Looper with Square Screen

Recently, I needed an affordable solution to loop videos on a small square screen to showcase some sketches. After researching, I found that a Raspberry Pi Zero with a Hyperpixel 4’ Square Screen was the most budget-friendly option. This particular screen connects via the Raspberry Pi’s GPIO pins rather than the HDMI port, which means typical solutions like MP4Museum weren’t compatible.

In this guide, I’ll walk you through the step-by-step process I used to get it working.

Notes:

Material list

ProductPriceCurrency
HyperPixel 4.0 Square Display55.90CHF
Raspberry Pi Raspberry Pi Zero WH14.51CHF
Kingston 64GB Canvas Select Mini SD Card6.82CHF
Micro USB Power Supply7.25CHF
USB A to Micro USB for Keyboard & Mouse2.29CHF
Total86.77CHF

Setting up the Raspberry Pi Zero

First, use the Raspberry Pi Imager to set up Raspberry Pi OS (Legacy, 32-bit) Full on an SD card. This option is available under Raspberry Pi OS (Other) and not directly on the imager’s main page.

After imaging, re-insert the SD card and open the config.txt file using a text editor. Add the following line1 at the beginning:

dtoverlay=vc4-kms-dpi-hyperpixel4sq

Then, add your video file to the video/video.mp4 path on the SD card. Using the boot directory makes it easy to access and swap out videos, although it only has about 200MB of free space.. If you need larger video files, consider using the larger partition.

Connect the Screen

Attach the display to your Raspberry Pi, but first, make sure to follow the correct pinout to avoid bricking your display, like I did the first time. To connect, hold the sides of the screen and gently wiggle it onto the pins. Avoid applying pressure directly to the display. Once connected, your Pi should boot up successfully with the screen. Be patient, as it takes around 5 minutes.

Working screen

Setting Up Video Looping

Create a systemd service file

sudo nano /etc/systemd/system/looping.service`

Populate it with the following content:

[Unit]
Description=Start video looper
After=network.target

[Service]
User=pi
ExecStart=/usr/bin/ffplay -loop 0 -vcodec h264_v4l2m2m /boot/video/video.mp4
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable the service and reboot the Pi. Note that startup time is slow, taking a few minutes to start the console and then the video:

sudo systemctl daemon-reload
sudo systemctl enable looper.service
sudo reboot -h now

If the service doesn’t start automatically, you can start it manually:

sudo systemctl start looper.service

Optimizing Video Playback

Initially, I had issues with video playback, where the video would pause at the end of each loop. To resolve this, I re-encoded the video using FFmpeg on my computer, resizing it to match the 720x720 HyperPixel 4 display resolution. This fixed the looping issue.

Here’s the command:

ffmpeg -i unoptimized.mp4 -vf "scale=720:720:force_original_aspect_ratio=decrease" -c:v h264 -movflags +faststart video.mp4

Multiple Video Loopers

To create multiple video loopers, I cloned the SD card to create a backup image file. This allowed me to easily replicate the same configuration across multiple SD cards.

First, I identified the SD card device name using the diskutil list. Then, I used the dd command to create a backup image file:

sudo dd if=/dev/YOUR_RASPBERRY_DISK_NAME of=IMAGE.img bs=4M oflag=direct status=progress

However, the resulting 64GB image file was too large, making it slow to copy to my 15 other SD cards. I used the dockerized version of Pishrink to reduce the size, getting it down to only 3GB.

docker run --privileged=true --rm \
    --volume $(pwd):/workdir \
    borgesnotes/pishrink:v0.1.4 \
    pishrink -Zv IMAGE.img NEW-IMAGE.img

With the new, smaller image file, I could quickly copy the image to all my SD cards using Raspberry Pi Imager. This smaller image also allows for flexibility with different SD card sizes, as it can be easily copied to smaller cards without issues, eliminating the need to set up the smallest card first and copy from that to others.

Footnotes

  1. This is specific to the square variant of the HyperPixel 4 display. For others, refer to this Github Issue