A picture frame enclosing an e-paper device which plays movies in a very slow manner.
- About
- License
- Prerequisites
- Get slow-movie-frame-10.3
- Configuration
- Installation
- Tests
- Acknowledgements
The scope/goal of this project was to create a picture frame enclosing an e-paper device which plays movies in a very slow manner.
This project was inspired by Tom Whitwell's Very Slow Movie Player which I have read about on Hackaday. Ever since, I wanted to create my own. So, eventually, I did.
To achieve the goal, a Waveshare 10.3 inch 16 gray scale color e-paper device and a Raspberry Pi Zero 2 W with Raspberry Pi OS for operating system were chosen.
While the software can be modified to run on different hardware and operating systems, doing so is out of the scope of this project.
The physical picture frame was made by Nagy Sándor Képkeretező Műhely és Művészbolt as I do not have the required tools and expertise create such a wonderful frame.
The project is structured in the following directories:
Directory | Description |
---|---|
build |
Directory meant to contain the compiled binaries of update-display and its tests. |
docs/img |
Directory containing images for this README. |
fixups |
Directory containing all non-source files (e.g. systemd service unit file, service configuration). |
src/slow-movie-player-service |
Python sources of the Slow Movie Player systemd service. |
src/update-display |
C sources of update-display . |
test/slow-movie-player-service |
Tests for Slow Movie Player. |
test/update-display |
C sources of the tests for update-display . |
vendor/easy-install-bcm2835 |
Submodule containing an easy-to-use installer for Mike McCauley's bcm2835 C library (required by IT8951-ePaper). |
vendor/IT8951-ePaper |
Submodule containing C library for Waveshare's e-paper devices driven by IT8951 (required by update-display ). |
This project is licensed under the MIT license. For the full license, please see LICENSE
.
-
Waveshare 10.3 inch 16 gray scale color e-paper device with IT8951 driver board (SKU: 18434).
-
Raspberry Pi Zero 2 W with GPIO headers installed.
-
The IT8951 driver board (of the e-paper device) installed to the GPIO header of the Raspberry Pi. (See the Waveshare 10.3 inch e-Paper HAT Wiki for details.)
-
The IT8951 driver board switched to SPI mode.
-
The e-paper screen connected to the driver board.
Make sure that the cables are connected properly: note the numberings on the IT8951 driver board PCB, the ribbon cable, and the e-paper screen's FPC.
-
Either the 32 or 64 bit version of Raspberry Pi OS (previously called Raspbian) installed on a large capacity microSD card. (It is recommended to use the Lite version of Raspberry Pi OS as no desktop is necessary for either setting up or running this project.)
-
Working internet connection for the duration of setting up this project. (Wireless or wired via a (micro-)USB Ethernet adapter.)
See the official Raspberry Pi configuration documentation how-to setup a wireless internet connection from the command-line.
-
SPI interfacing enabled.
See the official Raspberry Pi configuration documentation how-to enable SPI interfacing (under Interfacing Options) using
raspi-config
.
The following packages are required to run this project.
Package | Requirement description |
---|---|
build-essential |
Required by the vendor/easy-install-bcm2835 submodule and to build update-display . |
coreutils |
Required by the vendor/easy-install-bcm2835 submodule. |
findutils |
Required by the vendor/easy-install-bcm2835 submodule. |
git |
Required to acquire this project with all of its submodules. |
imagemagick |
Required by the Slow Movie Player Service for image processing. |
python3-numpy |
Required by the Slow Movie Player Service for image processing. |
python3-opencv |
Required by the Slow Movie Player Service for video processing. |
tar |
Required by the vendor/easy-install-bcm2835 submodule. |
wget |
Required by the vendor/easy-install-bcm2835 submodule. |
See the following commands for updating your Raspberry Pi OS and installing the necessary packages.
sudo apt-get update \
&& sudo apt-get dist-upgrade --yes \
&& sudo apt-get autoremove --purge --yes \
&& sudo apt-get autoclean \
&& sudo apt-get clean \
&& sudo reboot
sudo apt-get install build-essential coreutils findutils \
git imagemagick python3-numpy python3-opencv tar wget \
-o APT::Install-Suggests=0 \
-o APT::Install-Recommends=0 \
--yes
To acquire this project use the following git command to clone this repository with all of its submodules:
git clone --recurse-submodules https://github.com/szantaii/slow-movie-frame-10.3.git
The default configuration file (default.conf
) for the Slow Movie Player service can be found in the fixups directory. You can either edit the mentioned file or prepare your own configuration file for the Slow Movie Player service, however if the second approach is taken, then the setup.sh
script must be modified to copy the custom configuration file, or it has to be placed manually.
If you would like to edit your configuration after you have installed Slow Movie Player then you will have to edit the configuration file in the /etc/slow-movie-player
directory and restart the slow-movie-player.service
afterwards with the following command.
$ sudo systemctl restart slow-movie-player.service
Note that if you follow this approach and uninstall Slow Movie Player then your post-install edited configuration will be lost unless you make a backup of it.
Mandatory options and their respective types:
Option | Type |
---|---|
vcom |
float |
display_resolution |
string |
refresh_timeout |
non-negative float |
video_directory |
string |
Optional options and their respective types:
Option | Type |
---|---|
frame_skip |
positive integer |
time_skip |
positive float |
grayscale_method |
string |
random_frame |
boolean |
(Mandatory option, floating point number.)
This is the voltage for the connected e-paper device.
(Mandatory option, string.)
This is the resolution of the connected e-paper device.
Specify the string value in one of the following formats:
1872 1404
1872x1404
1872 x 1404
1872X1404
1872 X 1404
1872, 1404
1872; 1404
You may enclose the value between single or double quotes (e.g. '1872 x 1404'
) but it is not necessary.
(Mandatory option, non-negative floating point number.)
This is the amount of time (measured in seconds) while a single frame will be on the screen before advancing to the next one.
(Mandatory option, string.)
This is the absolute path to the directory which contain the videos you want to play with the Slow Movie Player Service.
You may enclose the value between single or double quotes (e.g. "/path/to/video/directory"
) but it is not necessary.
(frame_skip
: optional, positive integer.)
(time_skip
: optional, positive floating point number.)
frame_skip
is the amount of frames to advance in the video when advancing to the next frame to display. (Measured in number of frames.)
time_skip
is the amount of time, measured in milliseconds, to advance in the video when advancing to the next frame to display. (Measured in milliseconds.)
By adjusting these settings you may control how long the playback of videos will take with the Slow Movie Player Service.
frame_skip
and time_skip
are optional settings, so you may comment them out, in that case the Slow Movie Player Service will display all frames in videos. (Equivalent with specifying frame_skip = 1
.)
If both frame_skip
and time_skip
options are set, then the time_skip
option will take effect.
See the following examples for different playback durations with different frame_skip
and time_skip
settings.
Take a video with a 24 frames per second frame rate and with a 90 minute duration, frame_skip
set to 1 with refresh_timeout
set to 300.0 seconds (5 minutes).
In this case, the playback would roughly take up 90 × 60 × 24 × 300.0 seconds, or 450 days, or 1 year, 12 weeks and 1 day.
Take the same video and refresh_timeout
setting as in Example #1, but set frame_skip
to 3.
In this case the playback would take up (90 × 60 × 24) / 3 × 300.0 seconds which is only 150 days, or 21 weeks and 3 days.
Take a 45 minute video with a 48 frames per second frame rate and another 45 minute long video with a 29.97 frames per second frame rate, refresh_timeout
set to 300.0 seconds (5 minutes) and time_skip
set to 100.0 milliseconds.
In this case the total playback time of the two videos would take (45 + 45) × 60 × (1000 / 100.0) × 300.0 seconds, which is 26 weeks, 5 days and 12 hours.
Also note that the frame rate of the videos did not affect the total playback time in this case.
frame_skip = 1
: Every frame will be displayed.frame_skip = 2
: Only every other frame will be displayed.frame_skip = 10
: Only every tenth frame will be displayed.time_skip = 100.0
: A frame of every tenth of a second of the video will be displayed.
(Optional, string.)
This is the grayscale method which is applied to a video frame when applying Floyd-Steinberg dithering (along with a 4 bits per pixel color map).
Valid options are the following: Rec601Luma
, Rec601Luminance
, Rec709Luma
, Rec709Luminance
, Brightness
, Lightness
, Average
, RMS
.
See the following photo and the table below to see the effects of the different grayscale methods when creating 16 color dithered grayscale images.
The original photo is titled Two macaws, it was taken by Steve Kelly at Maui, Hawaii, USA on KODACOLOR Gold 100 Plus (35mm). (The original photo is Image #23 (Ref#JN1033) on the Kodak Photo CD Photo Sampler released by the Eastman Kodak Company.)
Grayscale method | Produced image |
---|---|
Rec601Luma |
![]() |
Rec601Luminance |
![]() |
Rec709Luma |
![]() |
Rec709Luminance |
![]() |
Brightness |
![]() |
Lightness |
![]() |
Average |
![]() |
RMS |
![]() |
All the images above were generated using ImageMagick with the following “one-liner”:
printf '%s\n' 'P2' '16 1' '255' '0' '17' '34' '51' '68' '85' '102' '119' '136' '153' '170' '187' '204' '221' '238' '255' > gray_palette.pgm && convert 'IMG0023.tif' -filter lanczos -resize 512x 'IMG0023_512x341.png' && for grayscale_method in 'Rec601Luma' 'Rec601Luminance' 'Rec709Luma' 'Rec709Luminance' 'Brightness' 'Lightness' 'Average' 'RMS' ; do convert 'IMG0023.tif' -filter lanczos -resize 512x -grayscale "${grayscale_method}" -dither FloydSteinberg -remap gray_palette.pgm "IMG0023_512x341_grayscale_${grayscale_method}_16grays.png" ; done
For further details about the grayscale methods, please see:
- ImageMagick Examples – Color Modifications – Converting Color to Gray-Scale
- ImageMagick – Annotated List of Command-line Options – grayscale
- ImageMagick – Annotated List of Command-line Options – intensity
grayscale_method
is optional, so you may comment out this setting. In this case the default Rec709Luma
grayscale method will be used.
You may enclose the value between single or double quotes (e.g. 'Rec601Luminance'
) but it is not necessary.
(Optional, boolean.)
By turning on this option, the Slow Movie Player Service will randomly display a frame from a random video in the video_directory
directory every refresh_timeout
seconds.
If this option is turned on, then then specified frame_skip
and time_skip
settings are not taken into account.
Valid options are the following: 1
, yes
, true
, on
and 0
, no
, false
, off
.
random_frame
is optional, so you may comment out this setting. In this case the random_frame
option is turned off.
-
Install Mike McCauley's bcm2835 C library.
This library is necessary to build
update-display
.sudo ./vendor/easy-install-bcm2835/setup.sh -i
In case you would like to remove slow-movie-frame-10.3 from your Raspberry Pi and do not need the bcm2835 C library anymore, run the same script with the
-u
switch to uninstall it.sudo ./vendor/easy-install-bcm2835/setup.sh -u
For further information on the
vendor/easy-install-bcm2835
submodule, see itsREADME.md
file. -
Compile
update-display
.cd ./src/update-display \ && make \ && cd ../..
-
Install the Slow Movie Player Service.
This will install the Slow Movie Player Python sources and C binary under
/opt
, the service configuration under/etc
, register the Slow Movie Player systemd service and enable it.sudo ./setup.sh -i
In case you would like to remove slow-movie-frame-10.3 from your Raspberry Pi, run the same script with the
-u
switch to uninstall it.sudo ./setup.sh -u
-
Add videos.
Create the directory you specified in
video_directory
and add the video files, which you would like the Slow Movie Player Service to play, into the directory. -
Disable internet connection (optional).
Since there is no further need for a working internet connection after this point, it is recommended to disable it.
See the following command to create a backup of your Raspberry Pi's
config.txt
file and to completely disable Bluetooth and Wi-Fi connections after a fresh boot on the Raspberry Pi.sudo sed -i.bak \ '$a \\n# Disable Bluetooth and Wi-Fi\ndtoverlay=disable-bt\ndtoverlay=disable-wifi\n' \ /boot/config.txt
For further details about the settings used in the command above see Device Trees, Overlays, and Parameters in the official Raspberry Pi documentation and this README about the specific options used.
-
Reboot the Raspberry Pi.
When the Raspberry Pi is rebooted Slow Movie Player Service will start to display video frames on the connected e-paper device after 60 seconds.
To run the tests for update-display
you will have to compile and run them:
cd ./test/update-display \
&& make \
&& cd ../.. \
&& ./build/test-update-display
To run the tests for the Slow Movie Player Service run the following Python script:
./test/slow-movie-player-service/testrunner.py
- Thanks to Mike McCauley for his bcm2835 C library for the Raspberry Pi as it provides a basis for a myriad of Raspberry Pi builds and projects.
- Thanks to Waveshare for providing easy to understand demos and an easy to use library for their IT8951 e-paper devices.
- Thanks to Péter Rácz for his help with reviews.
- Thanks to Nagy Sándor Képkeretező Műhely és Művészbolt for their great work on the physical picture frame.
- Thanks to all the other e-paper frame builds which provided inspiration: