RasPi4 with touch screen as living room media center with TV/Beamer autoswitch
I recently got a RasPi4 with official 7″ touch screen in a case and wanted to
make this my living-room media control center. I attached a video beamer to its
HDMI port (would also work for a TV set) and installed KODI.
My goal was to automatically restart Kodi and execute it on the video projector
screen, as soon as I turn on the device and restart it on the internal touch
screen when the device gets turned off again.
This way I can use the internal touch screen to i.e. listen to Internet Radio
or other live streams using the RasPi conveniently and also use it as a video
entertainment center when turning on the beamer.
This turned out to be not as easy as I initially thought it would be.
First of all, RaspiOS nowadays ships with the KMS/DRM video stack per default.
This is good for hardware accelleration and has a few other advantages, but is
bad for compatibility with the internal 7″ touchscreen display and KODI.
Here are the problems that I encountered:
- Current RaspiOS is based on debian Bullseye and only ships with KODI 19.
However, KODI 19 is missing a feature where its KMS backend can detect
multiple attached Screens (so in my case: Internal DSI-1 display and
external HDMI-1 display). So do most of the specialised Mediacenter
distributions like LibreELEC.
The first version that ships with KODI 20 is based on Debian Bookworm.
So RasPi needs to be updated to Debian Bookworm for KODI 20. - KODI 20 supports the detection of multiple screens (only can use one
of them at the same time, but that’s not a problem for me yet), but
it doesn’t support screen rotation in its KMS backend and doesn’t
obey the console rotation settings. This was a problem in my case, as
the screen got mounted upside-down in the case and due to the way the
case was designed, this also couldn’t be changed physically.
There is very few documentation about the KMS-DRM stack regarding rotation,
so I had to spend a huge amount of time into reading about the workings
of the KMS/DRM graphics stack, as most docuemntation just refers to X,
which isn’t used by KODI on RasPi (and shouldn’t be because of lack
in hardware accelleration). - The libcec library, that also
gets used by KODI internally for i.e. using the remote control of an
attached HDMI-device and other stuff, demands exclusive access to the
CEC interface, therefore I cannot monitor the CEC power status via
another libcec-Based daemon like
libcec-daemon
concurrently. - The FMKS-driver (vc4-fkms-v3d) supports rotation of the screen via
firmware, but doesn’t seem to detect HDMI properly (with attached
device in standby) and also doesn’t offer
CEC kernel support.
Therefore it is also unusable for my project.
So, how to solve all of these problems?
- Easy, just upgrade the OS to bookworm and we have a working KODI 20.
- Unfortunately, there didn’t seem to be a solution for KODI at the
time of writing. It just doesn’t have a setting for screen rotation
and the KMS-DRM requires the application driving the video screen to
set rotation itself. The Raspi-Docs just know about on how to let X
rotate the screen which isn’t what we need.
Therefore the only solution to this is to recompile kodi with a
hardcoded rotation for the internal DSI-1 port.
I made a little patch for Kodi and recompiled it for Debian bookworm
and documented everything in this
Github-Issue. It also documents on how to rotate the touch screen.
If you have the “brilliant” idea to rotate the screen from another
application by setting the rotation property of the active screen locked
by Kodi, like I did, I must disappoint you: You get “access denied”
in this case, so you have to bite the bullet and recompile kodi.
Altough I already provide a Debian package for it on the linked issue,
you can take the patch from there and recompile Kodi yourself, if you
want.
Approximately, this is something like:apt install build-essential devscripts apt source kodi apt build-dep kodi # Apply patch here export DEB_BUILD_OPTIONS="lang=en-US ccache nocheck" export EMAIL='leecher@dose.0wnz.at' dch -n debuild -us -uc -nc
- As libcec-daemon wasn’t usable for me due to mentioned reasons, I
wrote a little application to monitor the CEC0 port myself for changes
in power status and then execute a shell-script that restarts KODI
on change. The program is available in this github repo.
So in order to make the same installation as I did, here is a step-by-step
guide:
-
- Install RapiOS Bookworm
At the time of writing, Debian Bookworm wasn’t available as ready-made
distribution for the RasPi 4, so I had to install RaspiOS Bullseye and
then upgrade it.
If RaspOS based on Debian Bookworm or later is already available when you are
reading this, just install it with the RasPi Imager and you are good to go.
I selected the following
* Raspberry Pi OS (other)
* Raspberry Pi OS Lite (32-bit)Then, upgrade the newly-installed system(as root):apt update apt upgrade --without-new-pkgs sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list.d/* apt update apt full-upgrade reboot
- Install KODI (as root)
apt install kodi socat
2a) If your screen is swapped, install special 180° rotated version of KODI
(as root)wget https://github.com/xbmc/xbmc/files/12452936/kodi-bin_20.0%2Bdfsg-2.1_armhf.zip unzip kodi-bin_20.0+dfsg-2.1_armhf.zip rm kodi-bin_20.0+dfsg-2.1_armhf.zip dpkg -i kodi-bin_20.0+dfsg-2.1_armhf.deb sed -i "s/kodi-bin (<< 2:20.0+dfsg-2.1~), //g" /var/lib/dpkg/status vi /boot/cmdline.txt #add at the end of the first line: video=DSI-1:800x480M,rotate=180 echo 'ACTION=="add|change", KERNEL=="event[0-9]*", ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 0 -1 1"' >/etc/udev/rules.d/90-libinput-rotate.rules
- Install cec-powmon and necessary scripts (as normal user)
Ensure that you are running as normal user and not as root!cd ~ wget https://github.com/leecher1337/cecpowmon/archive/refs/heads/main.zip unzip main.zip rm main.zip mv cecpowmon-main cecpowmon cd cecpowmon make vi restart_kodi.sh
#!/bin/sh echo '{"jsonrpc":"2.0","method":"Application.Quit","id":1}' | socat -t 1 - TCP-CONNECT:localhost:9090
chmod 755 restart_kodi.sh vi start_kodi.sh
#!/bin/sh # Configure CEC for first use cec-ctl -d 0 --tv -S # Wait for HDMI status while : do STATUS=`cec-ctl --give-device-power-status --to 0` echo "$STATUS" | grep "pwr-state" >/dev/null if [ $? -eq 0 ]; then break fi sleep 2 done echo "$STATUS" | grep pwr-state | grep "on". if [ $? -eq 0 ]; then. OUTPUT=HDMI-A-1 SKIN=skin.estuary else. OUTPUT=DSI-1 SKIN=skin.estouchy fi echo "$OUTPUT$SKIN" >~/.kodi/userdata/advancedsettings.xml /usr/bin/kodi --standalone
chmod 755 start_kodi.sh mkdir -p ~/.kodi/userdata/ sudo vi /etc/systemd/system/kodi.service
[Unit] Description=Kodi Media Center After=remote-fs.target network-online.target Wants=network-online.target [Service] User=[username] Type = simple ExecStart=/home/[username]/cecpowmon/start_kodi.sh ExecStop=/bin/kill -TERM $MAINPID TimeoutStopSec=5 Restart=always RestartSec=2 StartLimitInterval=0 LimitNOFILE=16384 SyslogIdentifier = kodi # lowering memory fragmentation # https://linux.die.net/man/3/mallopt # https://github.com/xbmc/xbmc/pull/11620 Environment=MALLOC_MMAP_THRESHOLD_=131072 # Workaround for high CPU load with nvidia GFX Environment=__GL_YIELD=USLEEP [Install] WantedBy= multi-user.target
USER=`whoami` sudo sed -i "s/\[username\]/$USER/g" /etc/systemd/system/kodi.service sudo vi /etc/systemd/system/cecpowmon.service
[Unit] Description=HDMI CEC Monitor After=kodi.service Requires=multi-user.target Wants=network-online.target [Service] ExecStart=/home/[username]/cecpowmon/cecpowmon /home/[username]/cecpowmon/restart_kodi.sh ExecStop=/bin/kill -TERM $MAINPID TimeoutStopSec=5 Restart=always RestartSec=2 StartLimitInterval=0 LimitNOFILE=16384 [Install] WantedBy=default.target
USER=`whoami` sudo sed -i "s/\[username\]/$USER/g" /etc/systemd/system/cecpowmon.service sudo systemctl enable cecpowmon sudo systemctl enable kodi sudo systemctl daemon-reload sudo reboot
- Install RapiOS Bookworm
Now you should be greeted with KODI on one of the screens depending on
which you have turned on.