This project transforms your Raspberry Pi into a dedicated video playback device, ideal for display installations like a DIY Simpsons TV. It features two primary components: video_player
and button_handler
. These components interact to create a user-friendly media player with simple physical button-based controls. This project is inspired by Simpsons TV
The encode.py
script is a utility designed to encode video files into a format optimized for efficient playback on the Raspberry Pi. It utilizes the ffmpeg
tool to transcode videos into a format compatible with the hardware acceleration capabilities of the Raspberry Pi's GPU.
-
Video Detection: The script identifies video files within a specified directory by checking file extensions (e.g.,
.mp4
,.mkv
,.mov
,.avi
). -
Video Encoding: For each detected video file, the script transcodes it into the MP4 format using the H.264 codec. This format is preferred for its compatibility with hardware-accelerated decoding on the Raspberry Pi.
-
Optimization Parameters: The encoding parameters are chosen to balance file size and playback quality. These parameters include:
- Resolution: Resized to 320x240 pixels, optimized for a 2.8-inch screen.
- Codec: H.264 (libx264) with the baseline profile and level 3.0.
- Encoding Speed: Medium preset, balancing speed and file size.
- Compression: Constant Rate Factor (CRF) of 26 for moderately high compression.
- Pixel Format: YUV420P for compatibility with hardware decoding.
-
Concurrency: The script uses a thread pool to parallelize the encoding process, improving efficiency by leveraging multiple CPU cores.
Encoded video files will be saved in a subdirectory named encoded
within the specified directory.
The video_player
is a custom C program designed to efficiently manage and play a list of video files on the Raspberry Pi. It uses omxplayer
, a command-line media player optimized for the Raspberry Pi's GPU, ensuring smooth video playback even on less powerful models like the Raspberry Pi Zero.
- Hardware Accelerated Playback: Utilizes the GPU for decoding video, which minimizes CPU usage and ensures smooth playback.
- Automatic Video Looping: Automatically loops through a playlist of videos stored in a specified directory.
- Shuffle Playback: Randomizes the order of videos to provide a varied viewing experience each cycle.
- Signal Handling: Listens for signals to pause/resume playback and skip to the next video, allowing external control through physical buttons or other means.
The video_player
is executed at startup and continuously loops through all MP4 files located in a specified directory. It can be controlled externally via UNIX signals to pause/resume and change videos.
The button_handler
is a C program designed to interface with physical buttons connected to the GPIO pins of the Raspberry Pi. It provides physical controls for the video playback managed by video_player
, enhancing user interaction without the need for a graphical interface.
- Multi-Function Button Input: Differentiates between single, double, and long button presses to provide multiple controls:
- Single Press: Pauses or resumes the video playback.
- Double Press: Skips to the next video in the playlist.
- Long Press: Can be configured to perform actions like shutting down the Raspberry Pi or resetting the playlist.
- Debounce Logic: Implements software debouncing to ensure reliable button press detection.
- Signal Emission: Sends specific UNIX signals to
video_player
based on button inputs to control video playback.
The button_handler
monitors configured GPIO pins for button presses and sends commands to video_player
based on user interactions. It must be started at boot to listen for button presses continuously.
The Lite version of Raspberry Pi OS, doesn't include many of the desktop environment components, making it inherently faster to boot up than the full version. You've likely already chosen this, but it's important to reinforce its benefit for boot time optimization.
Raspberry Pi OS starts several services at boot that may not be necessary. Disabling these can speed up booting:
- Disable HDMI if your project doesn't require video output to a monitor:
Add the above line to
/usr/bin/tvservice -o
/etc/rc.local
beforeexit 0
to disable HDMI output at boot.
Adjust settings in /boot/config.txt
to skip some checks and speed up the boot process:
- Disable the Rainbow Screen: Add
disable_splash=1
. - Reduce boot delay: Set
boot_delay=0
to skip the delay before boot code execution.
Verbose logging can slow down the boot process:
- Configure
rsyslog
orsystemd-journald
to limit what is logged. - Edit
/boot/cmdline.txt
and adjust theconsole=
settings to reduce the amount of logging to the console during boot.
Make sure services start asynchronously to avoid waiting for one to finish before starting another. This is generally handled by systemd but check that dependencies are managed correctly so that non-critical services do not block the boot sequence.
Use systemd-analyze
to find out what's taking up the most time during boot:
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain
This tool shows you a breakdown of how long each service takes to start. Focus on optimizing or disabling the slowest services.
Before making any changes, ensure you have a backup of your SD card or important data.
- Update your system to ensure all packages are up to date:
sudo apt-get update sudo apt-get upgrade
- Move log files to a temporary filesystem (tmpfs):
Add these lines:
sudo nano /etc/fstab
Save and close the file.tmpfs /tmp tmpfs defaults,noatime,nosuid,size=100m 0 0 tmpfs /var/log tmpfs nosuid,nodev 0 0 tmpfs /var/tmp tmpfs nosuid,nodev 0 0
- Edit the
cmdline.txt
to mount the root filesystem as read-only:Find the root entry and modify it fromsudo nano /boot/cmdline.txt
root=/dev/mmcblk0p2
to:Additionally, addroot=/dev/mmcblk0p2 ro
fastboot noswap ro
at the end of the line.
-
Make DHCP client changes:
sudo rm /etc/systemd/system/dhcpcd5 sudo ln -s /lib/systemd/system/dhcpcd.service /etc/systemd/system/dhcpcd.service.dhcpcd5
-
Edit
dhcpcd
configuration to use a static IP or ensure it doesn't need to write:sudo nano /etc/dhcpcd.conf
This is optional and depends on whether you are using a static IP.
-
Adjust
systemd
to handle read-only root:sudo systemctl mask systemd-random-seed.service sudo ln -s /dev/null /etc/tmpfiles.d/dhcpcd.conf sudo ln -s /dev/null /etc/systemd/system/sysinit.target.wants/systemd-random-seed.service
To make changes after this setup, you'll need to remount the filesystem as read-write:
sudo mount -o remount,rw /
When done, remount it as read-only:
sudo mount -o remount,ro /
Check if everything boots up correctly and your applications function as expected in a read-only environment.
To completely disable networking on your Raspberry Pi, you can unload and blacklist the kernel modules responsible for network interfaces. Here's how to do it:
-
Open the cmdline.txt file to add networking disable commands:
sudo nano /boot/cmdline.txt
Add
ip=off
to the end of the line to disable DHCP and networking services. -
Blacklist Network Kernel Modules: Create a new blacklist file in the
/etc/modprobe.d/
directory:sudo nano /etc/modprobe.d/raspi-blacklist.conf
Add the following lines to disable Ethernet and Wi-Fi modules:
blacklist brcmfmac blacklist brcmutil blacklist smsc95xx blacklist lan78xx
This disables the drivers for the onboard WiFi and Ethernet (depending on your model of Raspberry Pi).
To disable Bluetooth, you need to blacklist its kernel modules and disable its system services.
- Add to the Blacklist File:
Open the previously created blacklist file:
Add the following lines:
sudo nano /etc/modprobe.d/raspi-blacklist.conf
blacklist btbcm blacklist hci_uart
- Disable Related Services:
Stop and disable Bluetooth services:
sudo systemctl disable bluetooth.service sudo systemctl disable hciuart.service
Disable the hardware interfaces directly from the bootloader configuration:
- Edit config.txt:
Add these lines to the end of the file:
sudo nano /boot/config.txt
This will completely disable the onboard WiFi and Bluetooth hardware interfaces.dtoverlay=disable-wifi dtoverlay=disable-bt
Ensure that no unnecessary services are started at boot:
- Modify systemd services to prevent networking services from starting:
sudo systemctl disable dhcpcd.service sudo systemctl mask networking.service
After making these changes, reboot your Raspberry Pi to ensure all changes take effect and the modules are not loaded:
sudo reboot
-
After rebooting, check that the network interfaces are indeed disabled:
ifconfig -a
This command should not show any active network interfaces except for
lo
(local loopback). -
Check Bluetooth status:
hciconfig
There should be no Bluetooth devices listed.
To use these systemd service files:
-
Place the service files in
/etc/systemd/system/
directory.sudo nano /etc/systemd/system/tvplayer.service sudo nano /etc/systemd/system/tvbutton.service
Copy and paste the content for each service file respectively and save them.
-
Reload the systemd manager configuration to recognize changes to service files.
sudo systemctl daemon-reload
-
Enable the services to start at boot.
sudo systemctl enable tvplayer.service sudo systemctl enable tvbutton.service
-
Start the services.
sudo systemctl start tvplayer.service sudo systemctl start tvbutton.service
-
Check the status of the services to ensure they are running correctly.
sudo systemctl status tvplayer.service sudo systemctl status tvbutton.service