divzeroweb

2f30.org website
git clone git://git.2f30.org/divzeroweb
Log | Files | Refs | README | LICENSE

rpi-tv.md (7928B)


      1 ### Raspberry Pi console media center with TV remote on Arch Linux
      2 
      3 This guide shows how to build a home entertainment system with the
      4 Raspberry Pi and Arch Linux on the console.  I made this as a
      5 replacement to XBMC which I was using before for watching stuff; only
      6 this setup also integrates nicely with MPD for accessing our music
      7 fast!
      8 
      9 
     10 #### Environment
     11 
     12 Most TVs nowadays support the CEC (Consumer Electronics Control)
     13 capability through the HDMI connection.  This lets us control other
     14 devices (such as the Raspberry Pi) using our remote.  The available
     15 buttons for CEC on my TV remote control are: Up, Down, Left, Right,
     16 Select, Exit.  The idea is to map those buttons to keyboard events using
     17 a `libcec` client and have programs configured to handle them.  Previous
     18 versions of this guide were using the `libcec-daemon` client but we have now
     19 switched to `ceckb` which is simpler and easy to build natively:
     20 
     21     https://git.2f30.org/ceckb/
     22 
     23 At the moment of writing, the default configuration in `config.h` is this:
     24 
     25     struct map bindings[] = {
     26         { CEC_USER_CONTROL_CODE_EXIT,    KEY_Q },
     27         { CEC_USER_CONTROL_CODE_SELECT,  KEY_ENTER },
     28         { CEC_USER_CONTROL_CODE_UP,      KEY_UP },
     29         { CEC_USER_CONTROL_CODE_DOWN,    KEY_DOWN },
     30         { CEC_USER_CONTROL_CODE_LEFT,    KEY_LEFT },
     31         { CEC_USER_CONTROL_CODE_RIGHT,   KEY_RIGHT },
     32     };
     33 
     34 And made the program start automatically as a service using our beloved
     35 init system.
     36 
     37 `/usr/local/lib/systemd/system/ceckb.service`:
     38 
     39     [Unit]
     40     Description = libcec to uinput key event mapper
     41     After = remote-fs.target
     42 
     43     [Service]
     44     User = root
     45     Group = root
     46     Type = simple
     47     ExecStart = /home/tv/bin/ceckb
     48     Restart = always
     49 
     50 Note that similar results can be achieved using a LIRC setup.  LIRC may
     51 be be a more flexible option simply because we'll probably have all
     52 buttons on the remote control to play with.  We won't explore that here
     53 however.
     54 
     55 So our keys now are:
     56 
     57   * Up
     58   * Down
     59   * Left
     60   * Right
     61   * Enter
     62   * q
     63 
     64 Let's see the programs selection and their configuration.
     65 
     66 
     67 #### The file browser
     68 
     69 The other main component of this setup is the actual filesystem
     70 navigation.  We will be using the `noice` file browser:
     71 
     72     https://git.2f30.org/noice/
     73 
     74 Build it with a custom `config.h` to match our available keys and file
     75 associations, using applications and wrapper scripts:
     76 
     77     struct assoc assocs[] = {
     78         { "anime/.*\\.mkv$", "omxplayer-audio-stream-two" },
     79         { "\\.(avi|mp4|mkv)$", "omxplayer-wrapper" },
     80         { "\\.(mp3|ogg|flac|m4a)$", "mplayer" },
     81         { "\\.radio$", "mpc-add-from-file" },
     82         { ".*", "less" },
     83     };
     84 
     85     struct key bindings[] = {
     86         { 'q',        SEL_BACK },
     87         { KEY_ENTER,  SEL_GOIN },
     88         { KEY_DOWN,   SEL_NEXT },
     89         { KEY_UP,     SEL_PREV },
     90         { KEY_RIGHT,  SEL_PGDN },
     91         { KEY_LEFT,   SEL_PGUP },
     92     };
     93 
     94 Of course we can also retain all other key bindings and resort to the
     95 keyboard for operations that don't make sense to support from the remote
     96 control.  With the wrappers we add functionality specific to our setup.
     97 For example using the `mpc-add-from-file`:
     98 
     99     #!/bin/sh
    100 
    101     cat $1 | mpc add
    102 
    103 We can create files with the `.radio` extension that contain radio
    104 stream URLs and organise them like that.  The action on them would add
    105 the stream to our running `mpd` queue.  We'll see the
    106 `omxplayer-wrapper` in more detail later on.
    107 
    108 
    109 #### Autostarting in file browser view
    110 
    111 Create a local user, let's say `tv`:
    112 
    113     $ useradd -m -g users -G audio,video tv
    114 
    115 Create the script `~tv/bin/tv-shell`:
    116 
    117     #!/bin/sh
    118 
    119     export PATH=$PATH:$HOME/bin
    120     cd $HOME
    121     noice menu/
    122 
    123 Make this script the default shell for user `tv` by editing `/etc/passwd`.
    124 
    125 And the menu will be the directory structure we will be navigating into
    126 using the remote control.  The last part is to auto-login the `tv` user,
    127 and can be done with an init script like this.
    128 
    129 `/usr/local/lib/systemd/system/getty@tty1.service.d/autologin.conf`:
    130 
    131     [Service]
    132     ExecStart=
    133     ExecStart=-/usr/bin/agetty --autologin tv --noclear %I 38400 linux
    134 
    135 
    136 #### The video player
    137 
    138 Install `omxplayer` from packages and create the following files with
    139 the appropriate ownership and permissions.
    140 
    141 `~tv/bin/omxplayer-wrapper`:
    142 
    143     #!/bin/sh
    144 
    145     args=
    146     args="$args --font /usr/share/fonts/TTF/DejaVuSans-Bold.ttf"
    147     args="$args --italic-font /usr/share/fonts/TTF/DejaVuSans-BoldOblique.ttf"
    148     args="$args --align center"
    149     args="$args --font-size 58"
    150     args="$args --no-ghost-box --blank"
    151 
    152     keyconf=~/.omxplayer/keys
    153     test -f "$keyconf" && {
    154         args="$args --key-config $keyconf"
    155     }
    156 
    157     subs="${1%.*}.srt"
    158     if test -f "$subs"; then
    159         omxplayer.bin $args --subtitle "$subs" "$1"
    160     else
    161         omxplayer.bin $args "$1"
    162     fi
    163 
    164 `~tv/.omxplayer/keys`:
    165 
    166     PAUSE: 
    167     PAUSE:hex 0xa
    168     SEEK_FORWARD_SMALL:right
    169     SEEK_BACK_SMALL:left
    170     SEEK_FORWARD_LARGE:up
    171     SEEK_BACK_LARGE:down
    172     EXIT:q
    173 
    174 The wrapper script selects subtitle fonts and looks for SubRip subtitle
    175 files (under the same name ignoring the file extension), among other
    176 preferences.  The other one specifies keybindings to match our remote
    177 control.  Note that the first line is a Space key and the second one is
    178 the key code for the Enter key.  You can use the `showkey` utility from
    179 the `kbd` package to identify key codes on the console.
    180 
    181 
    182 #### Setup MPD over NFS
    183 
    184 Create a link to our NFS mounted music directory:
    185 
    186     $ ln -s /mnt/store/music /var/lib/mpd/music/master
    187 
    188 We now create this configuration that uses the MPD database proxy plugin
    189 to receive metadata from a remote MPD instance instead of using it's
    190 local db file.
    191 
    192 `/etc/mpd.conf`:
    193 
    194     pid_file "/run/mpd/mpd.pid"
    195     state_file "/var/lib/mpd/mpdstate"
    196     playlist_directory "/home/tv/playlists"
    197     music_directory "/var/lib/mpd/music"
    198 
    199     database {
    200         plugin "proxy"
    201         host "store"
    202         port "6600"
    203     }
    204 
    205     input {
    206         plugin "curl"
    207     }
    208 
    209     audio_output {
    210         type            "alsa"
    211         name            "Speakers"
    212     }
    213 
    214 Care must be taken to have the file paths match in both our `store` host
    215 and here.  In this setup all MPD file paths will start with `master/`.
    216 Another thing is that playlists are not handled by the database so we
    217 need to synchronise them manually.  My choice is a private revision
    218 controlled playlists directory for that purpose.
    219 
    220 
    221 #### Audio visualizer
    222 
    223 We also build and install our console audio visualizer now:
    224 
    225     https://git.2f30.org/nausea/
    226 
    227 We need this to our `/etc/mpd.conf`:
    228 
    229     audio_output {
    230         type            "fifo"
    231         name            "Pipe"
    232         path            "/tmp/audio.fifo"
    233         format          "44100:16:2"
    234     }
    235 
    236 
    237 #### Youtube
    238 
    239 And if you need Youtube in your TV here is a Python package that deals
    240 with it:
    241 
    242     $ pip2 install mps-youtube
    243 
    244 To configure it to use our `omxplayer` wrapper script too:
    245 
    246     $ mpsyt
    247     > set player omxplayer-wrapper
    248 
    249 And video is disabled by default, so enable it:
    250 
    251     > set search_music false
    252     > set show_video true
    253 
    254 Note, however, that a keyboard will be needed for the searches here :)
    255 
    256 
    257 #### The glue
    258 
    259 Finally, under the `~tv/menu` directory we will be creating simple
    260 scripts and symlinks to organise our media files.
    261 
    262     $ ln -s /mnt/store/movies ~tv/menu/
    263     $ ln -s /mnt/store/series ~tv/menu/
    264 
    265 `~tv/menu/music.sh`:
    266 
    267     #!/bin/sh
    268 
    269     ncmpc
    270 
    271 `~tv/menu/music-off.sh`:
    272 
    273     #!/bin/sh
    274 
    275     mpc stop
    276 
    277 `~tv/menu/nausea.sh`:
    278 
    279     #!/bin/sh
    280 
    281     nausea -d 2
    282 
    283 
    284 #### Font size
    285 
    286 I've found that for my 32-inch 1366x768 native resolution TV, an 800x450
    287 console resolution is acceptable for the characters to be legible.  To
    288 change this edit `/boot/config.txt`:
    289 
    290     framebuffer_width=800
    291     framebuffer_height=450
    292 
    293 Another option is to use a terminal emulator like `fbterm`.  This way
    294 you get `fontconfig` and friends plus unicode support.
    295 
    296 
    297 Cheers!
    298 
    299 lostd@