Build a Raspberry Pi VHS player

published:

Build your own Raspberry Pi video player, that randomly plays snippets of old VHS footage from the archive.org VHS vault.

NOTE: this is from 2020. It may no longer be up to date. I may revisit and update this in the future, in the meantime you are on your own.

Read more about this project here.

To download the movies I used wget, based on this article. The command itself is just a oneliner, executed in multiple shells to download in parallel:

wget -r -H -nc -np -nH --cut-dirs=1 -e robots=off -A .mp4,.m4v,.mov,.webm,.avi -l1 -i ./source.txt -B 'http://archive.org/download/'

the source.txt, which was generated from crawling the html, has about 20000 lines and looks something like this:

wget -r -H -nc -np -nH --cut-dirs=1 -e robots=off -A .mp4,.m4v,.mov,.webm,.avi -l1 -i ./source.txt -B 'http://archive.org/download/'

I let the download run for about 30 hours and that gave me 320 videos. Thats 120 GB or 24 hours playtime in total. The complete VHS Vault is much larger.

The Raspberry Pi is a model 3B and uses a small 2GB microSD card with Raspbian Buster Lite. I installed some dependecies with

sudo apt install omxplayer mediainfo timelimit

I use omxplayer as the mediaplayer, because it is hardware accelerated on the Pi. mediainfo is for getting the length of a videofile and timelimit ends the omxplayer process after a specific time if the video is still playing.

#!/bin/bash

# dependencies: omxplayer mediainfo timelimit

MAXSECONDS=30 # maximum duration of clip

sudo mount -o ro /dev/sda1 /media/usb
FOLDER="/media/usb/videodrome"

while true; do # infinite loop

    pkill omxplayer # kill omxplayer if it is still active (somehow 'timelimit' does not do this)

    FILE=$( find "$FOLDER/" -type f -print0 | shuf -z -n 1 ) # pick random file
    clear # clear screen

    LENGTH="$(mediainfo --Inform="Video;%Duration%" $FILE)" # length is in ms
    if [ -z "$LENGTH" ]; then # cannot get length; just assume 60 seconds
        LENGTH=60000
    fi
    ((LENGTH=${LENGTH}/1000)) # convert to seconds
    ((MAXPOS=$LENGTH - 5))
    ((RANDOMPOS="$(shuf -i 0-$MAXPOS -n 1)")) # get a random position between 0 and $MAXPOS
    ((h=$RANDOMPOS/3600))
    ((m=($RANDOMPOS%3600)/60))
    ((s=$RANDOMPOS%60))
    RANDOMPOSOMX="$(printf "%02d:%02d:%02d" $h $m $s)" # convert to hh:mm:ss
    ((RANDOMLENGTH="$(shuf -i 0-$MAXSECONDS -n 1)"))
    timelimit -t $RANDOMLENGTH -T $RANDOMLENGTH -q omxplayer --pos $RANDOMPOSOMX --no-osd $FILE > /dev/null

done

The script to play the videos is just a small bash script that mounts an usb thumb drive, selects a random video from the drive, gets its length, selects a random position between 0 and the video length and generates a random clip length. It then uses omxplayer to play the videofile. The Pi 3B is fast enough to play the videos from archive.org without the need to convert them to a more suitable format. The Pi is set to Autologin (Console) and starts the bash script on log in. I also set the Overlay FS option in raspi-config and mount the usb-drive as read only to reduce data loss when unplugging the Pi. Because I use an old tube television with a scart connector I use the Pis composite output.

Long live the new flesh!


Have a comment? Drop me an email!
This helped you? Consider buying me a ♥ coffee ♥

Latest Notes

  1. Shadowdark - Player-Driven Death Mechanics
  2. Using Syncthing to back up photos from an Android phone
  3. Real Time Beat Prediction with Aubio
  4. Performant Images on the Web
  5. mdadm with bcache and btrfs