ctx->guides->rpi-tv
Raspberry Pi console media center with TV remote on Arch Linux
This guide shows how to build a home entertainment system with the Raspberry Pi and Arch Linux on the console. I made this as a replacement to XBMC which I was using before for watching stuff; only this setup also integrates nicely with MPD for accessing our music fast!
Environment
Most TVs nowadays support the CEC (Consumer Electronics Control)
capability through the HDMI connection. This lets us control other
devices (such as the Raspberry Pi) using our remote. The available
buttons for CEC on my TV remote control are: Up, Down, Left, Right,
Select, Exit. The idea is to map those buttons to keyboard events using
a libcec
client and have programs configured to handle them. Previous
versions of this guide were using the libcec-daemon
client but we have now
switched to ceckb
which is simpler and easy to build natively:
https://git.2f30.org/ceckb/
At the moment of writing, the default configuration in config.h
is this:
struct map bindings[] = {
{ CEC_USER_CONTROL_CODE_EXIT, KEY_Q },
{ CEC_USER_CONTROL_CODE_SELECT, KEY_ENTER },
{ CEC_USER_CONTROL_CODE_UP, KEY_UP },
{ CEC_USER_CONTROL_CODE_DOWN, KEY_DOWN },
{ CEC_USER_CONTROL_CODE_LEFT, KEY_LEFT },
{ CEC_USER_CONTROL_CODE_RIGHT, KEY_RIGHT },
};
And made the program start automatically as a service using our beloved init system.
/usr/local/lib/systemd/system/ceckb.service
:
[Unit]
Description = libcec to uinput key event mapper
After = remote-fs.target
[Service]
User = root
Group = root
Type = simple
ExecStart = /home/tv/bin/ceckb
Restart = always
Note that similar results can be achieved using a LIRC setup. LIRC may be be a more flexible option simply because we'll probably have all buttons on the remote control to play with. We won't explore that here however.
So our keys now are:
- Up
- Down
- Left
- Right
- Enter
- q
Let's see the programs selection and their configuration.
The file browser
The other main component of this setup is the actual filesystem
navigation. We will be using the noice
file browser:
https://git.2f30.org/noice/
Build it with a custom config.h
to match our available keys and file
associations, using applications and wrapper scripts:
struct assoc assocs[] = {
{ "anime/.*\\.mkv$", "omxplayer-audio-stream-two" },
{ "\\.(avi|mp4|mkv)$", "omxplayer-wrapper" },
{ "\\.(mp3|ogg|flac|m4a)$", "mplayer" },
{ "\\.radio$", "mpc-add-from-file" },
{ ".*", "less" },
};
struct key bindings[] = {
{ 'q', SEL_BACK },
{ KEY_ENTER, SEL_GOIN },
{ KEY_DOWN, SEL_NEXT },
{ KEY_UP, SEL_PREV },
{ KEY_RIGHT, SEL_PGDN },
{ KEY_LEFT, SEL_PGUP },
};
Of course we can also retain all other key bindings and resort to the
keyboard for operations that don't make sense to support from the remote
control. With the wrappers we add functionality specific to our setup.
For example using the mpc-add-from-file
:
#!/bin/sh
cat $1 | mpc add
We can create files with the .radio
extension that contain radio
stream URLs and organise them like that. The action on them would add
the stream to our running mpd
queue. We'll see the
omxplayer-wrapper
in more detail later on.
Autostarting in file browser view
Create a local user, let's say tv
:
$ useradd -m -g users -G audio,video tv
Create the script ~tv/bin/tv-shell
:
#!/bin/sh
export PATH=$PATH:$HOME/bin
cd $HOME
noice menu/
Make this script the default shell for user tv
by editing /etc/passwd
.
And the menu will be the directory structure we will be navigating into
using the remote control. The last part is to auto-login the tv
user,
and can be done with an init script like this.
/usr/local/lib/systemd/system/getty@tty1.service.d/autologin.conf
:
[Service]
ExecStart=
ExecStart=-/usr/bin/agetty --autologin tv --noclear %I 38400 linux
The video player
Install omxplayer
from packages and create the following files with
the appropriate ownership and permissions.
~tv/bin/omxplayer-wrapper
:
#!/bin/sh
args=
args="$args --font /usr/share/fonts/TTF/DejaVuSans-Bold.ttf"
args="$args --italic-font /usr/share/fonts/TTF/DejaVuSans-BoldOblique.ttf"
args="$args --align center"
args="$args --font-size 58"
args="$args --no-ghost-box --blank"
keyconf=~/.omxplayer/keys
test -f "$keyconf" && {
args="$args --key-config $keyconf"
}
subs="${1%.*}.srt"
if test -f "$subs"; then
omxplayer.bin $args --subtitle "$subs" "$1"
else
omxplayer.bin $args "$1"
fi
~tv/.omxplayer/keys
:
PAUSE:
PAUSE:hex 0xa
SEEK_FORWARD_SMALL:right
SEEK_BACK_SMALL:left
SEEK_FORWARD_LARGE:up
SEEK_BACK_LARGE:down
EXIT:q
The wrapper script selects subtitle fonts and looks for SubRip subtitle
files (under the same name ignoring the file extension), among other
preferences. The other one specifies keybindings to match our remote
control. Note that the first line is a Space key and the second one is
the key code for the Enter key. You can use the showkey
utility from
the kbd
package to identify key codes on the console.
Setup MPD over NFS
Create a link to our NFS mounted music directory:
$ ln -s /mnt/store/music /var/lib/mpd/music/master
We now create this configuration that uses the MPD database proxy plugin to receive metadata from a remote MPD instance instead of using it's local db file.
/etc/mpd.conf
:
pid_file "/run/mpd/mpd.pid"
state_file "/var/lib/mpd/mpdstate"
playlist_directory "/home/tv/playlists"
music_directory "/var/lib/mpd/music"
database {
plugin "proxy"
host "store"
port "6600"
}
input {
plugin "curl"
}
audio_output {
type "alsa"
name "Speakers"
}
Care must be taken to have the file paths match in both our store
host
and here. In this setup all MPD file paths will start with master/
.
Another thing is that playlists are not handled by the database so we
need to synchronise them manually. My choice is a private revision
controlled playlists directory for that purpose.
Audio visualizer
We also build and install our console audio visualizer now:
https://git.2f30.org/nausea/
We need this to our /etc/mpd.conf
:
audio_output {
type "fifo"
name "Pipe"
path "/tmp/audio.fifo"
format "44100:16:2"
}
Youtube
And if you need Youtube in your TV here is a Python package that deals with it:
$ pip2 install mps-youtube
To configure it to use our omxplayer
wrapper script too:
$ mpsyt
> set player omxplayer-wrapper
And video is disabled by default, so enable it:
> set search_music false
> set show_video true
Note, however, that a keyboard will be needed for the searches here :)
The glue
Finally, under the ~tv/menu
directory we will be creating simple
scripts and symlinks to organise our media files.
$ ln -s /mnt/store/movies ~tv/menu/
$ ln -s /mnt/store/series ~tv/menu/
~tv/menu/music.sh
:
#!/bin/sh
ncmpc
~tv/menu/music-off.sh
:
#!/bin/sh
mpc stop
~tv/menu/nausea.sh
:
#!/bin/sh
nausea -d 2
Font size
I've found that for my 32-inch 1366x768 native resolution TV, an 800x450
console resolution is acceptable for the characters to be legible. To
change this edit /boot/config.txt
:
framebuffer_width=800
framebuffer_height=450
Another option is to use a terminal emulator like fbterm
. This way
you get fontconfig
and friends plus unicode support.
Cheers!
lostd@