I used to have a “home entertainment system” to play music (MP3), radio (web streams) and movies (via a beamer). The music/radio portion ran on a raspberry pi 1, the movies I played from a Lenovo desktop.
However, all parts were om the edge of their usable lifetime or already broken.

Old setup

My old setup consisted of:

  • Amplifier: Yamaha AX-492
  • Speakers: JBL (SMS-100 subwoofer, 2 100SAT satellite speaker)
  • Video: BenQ TW 529 projector
  • Media center 1: Raspberry Pi 1 to play audio (music or web radio, homebrew distro, which I call MPDpi because all it does is play via MPD)
  • Media center 2: A Lenovo desktop I got on the cheap, to play movies

The speakers were broken: the satellite speakers had the cone foam broken. The amplifier (originally from I think from 1999) was recently renovated by a friend. That same friend sold me a pair of Dali speakers.

The Rapsberry Pi 1 is still my daily driver for music and web radio streams. I have an IR sensor hooked up to it and can control it with a remote control and my phone. However, it lacked some functionality I had earlier after I had to reinstall it due to an SD card crash, like detection of the power state of the amplifier, and a shutdown button.

I had bricked the Lenovo pc I used to run Kodi in mid 2019. I bought a Raspberry Pi 3 to replace it, and two days after that (I had not even recieved it), the RPi 4 was announced. However, the end of the year is always a busy time for me, and then came covid, and countrary to the rest of the whole working world, I was busier than ever with work and certainly did not have time to tinker.

Also, behind all the equipment there was a horrible mess of cables.

Project goal

My goal for this project is the following:

  • Have one device for both music and video (Kodi)
  • Install the better Dali speakers
  • Easy to control
  • Make my bookcase look cleaner
  • Ideally: be able to stream audio (over bluetooth) to the speakers, and to stream video (casting) to the beamer
  • Ideally: be able to play retro games
  • Ideally: be able to use Youtube, NPO Start

Cleaning up

First order of business was cleaning up.
I removed all cables that I didn’t use. Moved my router (that was in the same area) to on top of my bookcase for better reception and put the speakers where I wanted them.

Then, I installed new speakers. Unfortunately, the only speaker cables I had were old, severely oxidized, and a few centimeters too short. But even then, the sound quality was formidably better. The old speakers were literally ringing from having perished foam around the speaker cones.

One problem with the new speakers is that they are much more directional than the old ones. They are meant to be used directly aimed at the listener (say: on the sides of a TV), but I did offend all audiophiles by installing them in a bookcase (they are called bookshelf speakers) behind the couch, relying on the wall reflecting the sound.
In a later episode, I will also offend all videophiles by projecting my video on a rough painted-white wall.
I had to get used to the sound of the speakers, but by increasing the loudness setting on the amp a tiny bit I got a good compromise between sound quality walking around the house and sitting on my sofa. Update: It was really a matter of getting used to the new, better sound – I removed all loudness and it still sounds great.

A few weeks later, I installed newer new speaker cables: they are new, non-oxidized, a little bit thinner, but I have the feeling the sound was a lot better already.

Setting up a temporary workspace

I like to first have a temporary setup to be able to work on the Raspberry Pi on my desk, next to my work pc.
I needed the following devices and cables:

  • Image: Monitor, Mini HDMI to HDMI, HDMI Cable, HDMI to DVI-convertor, Power cord
  • Audio: Trust Leto (Cheapest speakers available), Hifiberry DAC+, Tulip-to-3.5mm jack, 3.5mm jack splitter
  • Connectivity: Network cable
  • Misc: USB power brick, USB-A to USB-C cable, mouse, keyboard

A little plugging and finding cables later (the HDMI cable I had turned out to be HDMI to Displayport, I had to dig deep in my cable drawer for a HDMI-HDMI cable and switch the old monitor, that had only VGA and DVI, for one of the monitors that’s on my computer, which has HDMI as well) the monitor did not display anything, and the RPi blinked a led 4 times, which means “start*.elf not found”. So, the SD Card that was already in the Pi had no usable image.

I had decided earlier on an install of retropie, as it promised it would run Kodi without too much clutter. This turned out to not be the case for me.

Dealing with a faulty SD card

I downloaded a new RetroPie image and installed it with step 2 from my Basic Raspberry Pi Headless Wired install, which is copying the image file over to the SD card. I did this with dd in a terminal window in Dolphin, but that would stop showing status updates after ± 20s, and was unkillable, except by pulling out the SD card. In a Konsole terminal it did copy over to the card, with an astounding 1.6MB/s. However, it seemed to hang after fully writing. Apparently, this is somewhat normal behaviour of using conv=fsync. However, even without the conv=fsync, dd hung a few times.
Testing with Badblocks I found

$ sudo badblocks -n -v /dev/sdj
Checking for bad blocks in non-destructive read-write mode
From block 0 to 7802879
Testing with random pattern:
0
1
…
447
badblocks: Input/output error during test data write, block 448
448
449
450

It found multiple bad blocks. Due to wear leveling, an SD card should self-clear bad blocks and never have any bad block. According to this post, even one bad block means a broken SD card. I tossed this one.

Another card gave

$ sudo badblocks -n -v /dev/sdj
Checking for bad blocks in non-destructive read-write mode
From block 0 to 7761919
Testing with random pattern: Pass completed, 0 bad blocks found. (0/0/0 errors)

Back in business

The good SD card meant I could continue with step 2 from my Basic Raspberry Pi Headless Wired install:

$ sudo dd bs=4M if=retropie-buster-4.8-rpi4_400.img of=/dev/sdj status=progress
3148873728 bytes (3,1 GB, 2,9 GiB) copied, 208 s, 15,1 MB/s
750+1 records in
750+1 records out
3148873728 bytes (3,1 GB, 2,9 GiB) copied, 587,84 s, 5,4 MB/s

So, finally a clean install!

Then, I did steps 3-9 of my basic Pi install (choosing 192.168.15.4 as IP and using retropie as hostname, for now). This worked fine and I could login via ssh.

Installing the Hifiberry

Next, I wanted to try the Hifiberry, which is a DAC (digital to analog converter) for the Raspberry Pi. It can do audio conversion with a dedicated chip with more precision than the CPU of the Raspberry Pi can, and it is dedicated. So it promises better sound quality.

First check: did the Raspberry (with Hifiberry) play any sound at all? I connected the speakers to the headphone jack, installed mpg123 and tried to play the stream for Studio Brussel:

sudo apt-get install mpg123
mpg123 http://icecast.vrtcdn.be/stubru-high.mp3

Initially, I got no sound. I found a solution by Dengfeng, which is to disable the HDMI and composite video in raspi-config:
sudo raspi-config6 Advanced optionsA8 HDMI / CompositeDisable 4Kp60 HDMI and composite video and then reboot. This made audio work. However, I still had no video! It turned out that my combination of Mini HDMI to HDMI + HDMI (male-male) cable + HDMI to DVI converter was not working.
←This will disable video entirely, which is not what I want obviously!
I found out that the sound is played by default through HDMI and can be moved to the headphone jack (which can also do composite video, if I ever want to attach an old-fashioned tv) in raspi-config under 1 system optionsS2 AudioHeadphone output→select Jack output.

Next, I installed my Hifiberry, which was just a matter of popping it on top of the Pi.
I ran in a bit of problem with connecting the speaker: they had a male 3.5mm jack plug. The Hifiberry I chose only had RCA plugs, and I only had RCA to male 3.5mm cables that I was not willing to sacrifice. I am sure I must have a female-female 3.5mm jack splitter somewhere, but I could not find it. However, I did find a 3.5mm splitter (for if you want to listen with two headphones to one walkman) and realized that also can act as a female-female converter. Just don’t let the male prong touch anything conductive.

This setup did not produce any sound at the first try.
From the hifiberry config page:

In /boot/config.txt:

  • Comment the line #dtparam=audio=on
  • Add audio-off to dtoverlay=vc4-fkms-v3d,audio=off
    (or, if the line was had “kms” instead of fkms: add ,noaudio:
    dtoverlay=vc4-kms-v3d,noaudio)
  • Add the line dtoverlay=hifiberry-dacplus

On reboot, aplay -l showed

**** List of PLAYBACK Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_dacplus], device 0: HiFiBerry DAC+ HiFi pcm512x-hifi-0 [HiFiBerry DAC+ Hi
Fi pcm512x-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0

This is good. But …

pi@retropie:~ $ mpg123 http://icecast.vrtcdn.be/stubru-high.mp3
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
version 1.25.10; written and copyright by Michael Hipp and others
free software (LGPL) without any warranty but with best wishes
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Segmentation fault

Turned out I forgot to configure alsa in /etc/asound.conf. I added:

pcm.!default {
   type hw card 0
}
ctl.!default {
   type hw card 0
}

And then it worked!
Nice! I have a base system setup, with a working audio via the Hifiberry!

Installing Kodi (part 1)

I had installed Retropie above. But it kept crashing, and even audio output from the terminal was slow, so I decided I wanted something more stable, so instead I decided to install a vanilla Raspberry Pi OS (the new name for Raspbian) Lite (without X) using their Imager.
After going through all the steps I had done before, the command to install kodi is just

sudo apt install kodi

That pulls in a whole lot of packages (240, including everything needed for X), but afterward, running

kodi-standalone

I was greeted by the Kodi home screen with some Kodi installation settings!
That was easy!

Note that the GPU split apparently needs to be 256MB (“at least 160MB”) for kodi, this can be changed with raspi-config.

I immediately added the option to control kodi from HTTP from settings→Control→Allow remote control via HTTP. I could now control Kodi from Kore, the official Kodi Android app.

I decided not to go on with the Kodi install for now, but make the audio portion work first.

Installing NFS

On my NAS, I have a NFS share with all my movies and audio on it. I roughly followed a guide at PiMyLifeup. First step should be to install NFS-common (sudo apt-get install nfs-common), but that was already installed. Then I made a mountpoint and manually mounted the NFS drive:

mkdir /media/nfsMovieDisk
sudo mount -t nfs -o proto=tcp,port=2049 192.168.15.2:/ /media/nfsMovieDisk

This worked. To automatically boot the NFS share, I can put a line for it in /etc/fstab. I copied the line from my MPDpi:

192.168.15.2:/  /media/nfsMovieDisk     nfs4    defaults    0       2

This means: mount the (shared) root of 192.168.15.2 (my NAS) at /media/nfsMovieDisk, type nfs4, default options, no backup, not the first device to boot.

A quick reboot confirmed that the NAS drive was mounted at boot.

Installing MPD

What I want from the raspberry pi is to play audio (web streams and mp3’s stored on another computer) using MPD, and operate mpd via both an IR remote control and the MPDroid app.

I just tried

sudo apt-get install mpd

Then I edited the /etc/mpd.conf according to what I had in my MPDpi. Notably, the lines with

  • music_directory: "/media/nfsMovieDisk/Audio"
  • bind_to_address: "any"

I added a few streams to /var/lib/mpd/playlists (giving those files user mpd with a sudo chown mpd <filename>.m3u, and updated the library by typing (from another computer)

mpc --host=192.168.15.4 update --wait

The mpdroid app on my phone would connect to mpd and play mp3’s from my NFS share happily. When playing a web radio stream, it would take about 10 seconds to start, and sometimes pause for a second. I could not find an immediate solution. Then I remembered mpg123 was also very slow to start a stream. I spent an hour googling, no one seemed to have the same problem, but I did find a remark about network configuration. That made me wonder whether my network was setup right. A quick test revealed it wasn’t:

$ping icecast.vrtcdn.be
PING icecast.vrtcdn.be(2600:9000:238d:7a00:14:8356:dcc0:93a1 (2600:9000:238d:7a00:14:8356:dcc0:93a1)) 56 data bytes
64 bytes from 2600:9000:238d:7a00:14:8356:dcc0:93a1 (2600:9000:238d:7a00:14:8356:dcc0:93a1): icmp_seq=1 ttl=58 time=
10.2 ms
64 bytes from 2600:9000:238d:7a00:14:8356:dcc0:93a1 (2600:9000:238d:7a00:14:8356:dcc0:93a1): icmp_seq=2 ttl=58 time=
10.3 ms

The first result took over 15 second to show up. My mpdpi had about similar ping times, but with IPv4 the first line came a lot faster.

This thread offered no direct help, but made me think the problem lay in the dns resolving.

My /etc/resolv.conf was

# Generated by resolvconf
nameserver 192.168.0.1
nameserver 8.8.8.8
nameserver fd51:42f8:caae:d92e::1
nameserver fd00::3ea6:2fff:fe8e:1f24

The first line pointed to a non-existing nameserver, as I chose to have my local domain be 192.168.15/24.

In step 8 of my Basic Raspberry Pi Headless Wired install, I set the nameservers in /etc/dhcpcd.conf. Indeed, I had forgotten to update the domain_name_servers to 192.168.15.1. After I did that, Ping and playing mpd web streams were now lightning fast!

Installing LIRC

I want to recieve (and possibly later send) infrared (IR) systems from a remote control and use that to control the media centre. LIRC (Linux InfraRed Control) can do that (and did that on my mpdpi). To recieve infrared signals from remote controls, I need to connect an IR reciever to the raspberry Pi. However, the Hifiberry takes up the entire pin header where you’d normally attach GPIO, but has space for another pin header that I had to solder on (voiding the warranty).

However, there are several pins that are reserved: GPIO 0-3 and 18-21, which turn out to be GPIO pins 27, 28, 3, 5, 12, 35, 38, 40, respectively). This means I have all other pins available to me. Because I only had a 26 (2×13) female pin header, I decided to only put the header pins on pins 1-26, but omitting reserved pins 3,5 and 12. Luck would have it that I had a 22 pin header, and I snapped one pin off from another header.

I was happy at my soldering job: apart from a few scars at the plastic header, it went reasonably well, and I tested all pins for connectivity and not having shorts with any of it’s neighbors.

I also needed an infrared reciever. The one I had was connected to a 2.5mm jack, but I had an IR reciever connected to serial port that I made in 2001, the whole thing put in a CD jewelcase. As it was set up for the higher serial port voltages, I solder-tacked a cable directly to the TSOP1738. The other end, I made from the audio connectors of and old PC: pink for the IR reciever, and maybe I want to try an IR sender later, so I reserved the green one for that. Figuring out the pins for those connectors took me some time, turns out each has 5 pins: one for ground, left and right audio, and two that connected to detect when a jack plug was inserted.
I connected the tip to +5V, ring to the GPIO and sleeve to ground. (I later found out that this makes the system non-hotpluggable: the RPi reboots on inserting the jack plug).
The two female audio connectors were on a little breakout board which had a 10 pin header, that connected to two other 10 pin headers for use on the mainboard, one labelled “AC ’97” and the other “HD Audio”. I decided to use these headers temporarily, rewiring them so one was used for power and ground (covering pins 1-10) and the other for GPIO 25 (pin 22), and the future blaster to GPIO 11 (pin 23) (covering pins 21-30, with pins 26-30 not populated).

With the hardware part complete, now the software. I followed this guide from [alexba], which is ancient (from 2013), but I found the url it in my old MPDpi’s /boot/config.txt, and a more up-to-date (but less structured) instructable.

First: install LIRC:

sudo apt-get install lirc

You don’t need to add things to /etc/modules as written in the Alexba manual anymore. Instead, add one line to /boot/config.txt: (and note that dtoverlay=lirc-rpi is ancient as well, use gpio-ir).

# Note: these are GPIO numbers, not pin numbers!
dtoverlay=gpio-ir,gpio_pin=25
#dtoverlay=gpio-ir-tx,gpio_pin=22 #disabled because I don't use it yet

To test whether infrared reception works, use the program mode2, which shows the raw output of a remote. First stop the lirc service, then use mode2 to test:

$sudo systemctl stop lircd.service
$sudo mode2 -d /dev/lirc0  
Using driver devinput on device /dev/lirc0
Trying device: /dev/lirc0
Using device: /dev/lirc0
Running as regular user pi
code: 0x7c381f0014c51e006b23000149110000
code: 0x7b020001ee0100007f0200015b060000
code: 0x65020001ee0100007e0200015b060000
code: 0x640200015a0600007f02000141060000
code: 0x7e0200015b06000065020001ee010000
Partial read 4 bytes on /dev/lirc0pi@kodipi:~ $

It did respond to button presses of a remote, but not in a format I expected, and after one press it quit. A quick google led to this question from stackoverflow. The solution was to change two lines in /etc/lirc/lirc_options.conf:
driver          = default
device          = /dev/lirc0

This gave me the expected results with mode2:

$sudo mode2 -d /dev/lirc0 
Using driver default on device /dev/lirc0
Trying device: /dev/lirc0
Using device: /dev/lirc0
Running as regular user pi
pulse 9071
space 4443
pulse 613
space 493
pulse 641
.....
space 39881
pulse 9069
space 2178
pulse 638
timeout 135368

This means my IR reciever recieves remote control signals!

Next step, is to define actions based on button presses. For example, if I want to play or stop the music when I press the “pause” button. For that I first need mpc, which is the reference implementation of the client for the mpd.

sudo apt-get install mpc
mpc pause

This just worked: the playing stream stopped (and a mpc play restarted it)

Lirc has a helper program, irexec, that can run other programs when recieving button presses. The two main configuration files are /etc/lirc/lircd.conf.d/<name>.conf (one for each remote) and /etc/lirc/irexec.lircrc (this used to be /etc/lirc/lircrc).

I copied over the file irexec.lircrc from my old mpdPi’s lircrc. However, it did not work immediately. After reading the irexec man page, I found that irexec has it’s own service, which needs to be started. sudo systemctl start irexec starts the service, and now the pause button on my remote stops the music playing. However, irexec would not automatically start at boot.

Raspberry Pi OS now uses systemd to start services. I found this useful introduction to systemd (specifically for the RPi). In the end, it was as simple as

sudo systemctl enable irexec

I did make a few changes to /usr/lib/systemd/system/irexec.service, for which I submitted a bug to raspbian: I added the program name to the description line (as well as for lircd.service and lircd-setup.service) and added After=multi-user.target lircd.service (to describe when it should start). This made the startup messages a lot clearer and lirc and irexec immediately follow each other.

Lirc config files

There are two config file(sets) that are very important: the definition of remote controls and the actions to be taken.

For the remote controls, there used to be a file /etc/lircd.conf where you had to put all your “remote” configurations in one file. That is replaced with one file per remote in the directory /etc/lirc/lircd.conf.d/. You can record a remote with LIRC’s IRrecord. But, I already had a configuration file on my MPDpi, so I copied that and split it into three files for three different remotes.
The file for the Yamaha RAX1 I have is

# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.0-pre1(default) on Mon Mar  3 22:35:39 2014
#
# contributed by 
#
# brand:                       Yamaha
# model no. of remote control: RAX1 (VU07410)
# devices being controlled by this remote:
#

begin remote

  name  Yamaha_RAX1
  bits           16
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       9039  4458
  one           602  1647
  zero          602   522
  ptrail        598
  repeat       9039  2211
  pre_data_bits   16
  pre_data       0x5EA1
  gap          108000
  toggle_bit_mask 0x0

      begin codes
          SELECT_AUX               0xE817
          SELECT_TAPE2             0x9867
          SELECT_TAPE1             0x18E7
          SELECT_TUNER             0x6897
          SELECT_CD                0xA857
          SELECT_PHONO             0x28D7
          VOLUME_UP                0x58A7
          VOLUME_DOWN              0xD827
          POWER                    0xF807
          TAPE_DIRA                0xE01F
          TAPE_DIRB                0x02FD
          TAPE_REC/PAUSE           0x20DF
          TAPE_PLAY                0x00FF
          TAPE_STOP                0xC03F
          TAPE_A/B                 0x609F
          TAPE_<<                  0x807F
          TAPE_>>                  0x40BF
          TUNER_PRESET-            0x8877
          TUNER_PRESET+            0x08F7
          TUNER_A/B/C/D/E          0x48B7
          CD_<<                    0xB04F
          CD_>>                    0x30CF
          CD_|<<                   0xD02F
          CD_>>|                   0x50AF
          CD_DISC                  0xF20D
          CD_PLAY                  0x10EF
          CD_STOP/PAUSE            0x906F
      end codes

end remote

The irexec.lircrc file lists all actions for the remote:

begin radio
begin
        prog = irexec
        button = CD_STOP/PAUSE 
        config = mpc stop
        flags = quit
        repeat = 0
end  
begin
        prog = irexec
        button = CD_DISC
        config = mpc-play music
        repeat = 0
        flags = mode
end
end radio

begin
        prog = irexec
        button = TUNER_PRESET- 
        config = mpc-play StuBru
        repeat = 0
        mode = radio
end  
begin
        prog = irexec
        button = TUNER_PRESET+ 
        config = mpc-play "Radio 1"
        repeat = 0
        mode = radio
end  
begin
        prog = irexec
        button = CD_DISC
        config = mpc play
        repeat = 0
end
begin
        prog = irexec
        button = POWER
        config = mpc stop
        repeat = 0
end
begin
        prog = irexec
        button = CD_<<
        config = mpc seek -0:00:10
        repeat = 1
        delay = 4
end  
begin
        prog = irexec
        button = CD_>>
        config = mpc seek +0:00:10
        repeat = 1
        delay = 4
end  
begin
        prog = irexec
        button = CD_|<<
        config = mpc prev
        repeat = 0
end  
begin
        prog = irexec
        button = CD_>>|
        config = mpc next
        repeat = 0
end  
begin
        prog = irexec
        button = CD_PLAY
        config = mpc play
        repeat = 0
end  
begin
        prog = irexec
        button = CD_STOP/PAUSE 
        config = mpc pause
        repeat = 0
end  
begin
        prog = irexec
        button = KEY_UP 
        config = kodi-send Up
        repeat = 3
        delay  = 8
end  
begin
        prog = irexec
        button = KEY_DOWN 
        config = kodi-send Down
        repeat = 3
        delay  = 8
end  
begin
        prog = irexec
        button = KEY_LEFT 
        config = kodi-send Left
end  
begin
        prog = irexec
        button = KEY_RIGHT 
        config = kodi-send Right
        repeat = 3
        delay  = 8
end  
begin
        prog = irexec
        button = KEY_TV
        config = kodi-send Back
        repeat = 0
end  
begin
        prog = irexec
        button = KEY_OK 
        config = kodi-send Select
        repeat = 0
end  
begin
        prog = irexec
        button = KEY_INFO 
        config = kodi-send Info
        repeat = 0
end  
begin
        prog = irexec
        button = KEY_CONTEXT_MENU 
        config = kodi-send ShowOSD
        repeat = 0
end  
begin
        prog = irexec
        button = KEY_0 
        config = kodi-send Pause
        repeat = 0
end
begin
        prog = irexec
        button = KEY_MUTE 
        config = kodi-send Mute
        repeat = 0
end  
begin
        prog = irexec
        button = DVD_rewind 
        config = kodi-send Rewind
        repeat = 0
end  
begin
        prog = irexec
        button = DVD_play 
        config = kodi-send Play
        repeat = 0
end  
begin
        prog = irexec
        button = DVD_fastforward
        config = kodi-send Forward
        repeat = 0
end  
begin
        prog = irexec
        button = DVD_stop
        config = kodi-send Stop
        repeat = 0
end  
begin
        prog = irexec
        button = DVD_power
        config = kodi-send Kodi-on
        repeat = 0
end  

irexec requires two helper scripts: one for controlling kodi and one for controlling the mpd playlists.

/usr/local/sbin/kodi-send is a bash shell script that I made to control Kodi on a different pc. I will work on it later.

#!/bin/bash

HOST=http://localhost:8080/jsonrpc
#MACaddress=d8:cb:8a:45:da:a0

case $1 in
Mute)
  COMMAND=Application.SetMute
  ;;
Up)
  COMMAND=Input.Up
  ;;
Down)
  COMMAND=Input.Down
  ;;
Left)
  COMMAND=Input.Left
  ;;
Right)
  COMMAND=Input.Right
  ;;
Select)
  COMMAND=Input.Select
  ;;
Info)
  COMMAND=Input.Info
  ;;
ShowOSD)
  COMMAND=Input.ShowOSD
  ;;
Back)
  COMMAND=Input.Back
  ;;
Pause)
  COMMAND=Player.PlayPause
  PARAMS=', "params":{"playerid":1}'
  ;;
Context_menu)
  COMMAND=Input.ContextMenu
  ;;
Play)
  COMMAND=
  ;;
Rewind)
  COMMAND=Player.Seek
  PARAMS=', "params":{"playerid":1,"value":"smallbackward"}'
  ;;
Forward)
  COMMAND=Player.Seek
  PARAMS=', "params":{"playerid":1,"value":"smallforward"}'
  ;;
Stop)
  COMMAND=Player.Stop
  PARAMS=', "params":{"playerid":1}'
  ;;
# No longer used - this was used to wake up a secondary pc that ran kodi. Now this is all on the same machine.
#Kodi-on)
#  wakeonlan $MACaddress
#  exit
#  ;;
*)
  echo "Wrong Command"
  exit
  ;;
esac

#echo $COMMAND
LONGCOMMAND="{\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"$COMMAND\"$PARAMS}"
#echo $LONGCOMMAND

curl -s -d "$LONGCOMMAND" -H 'content-type: application/json;'  $HOST
echo `date` $LONGCOMMAND >> /home/pi/lirc/kodisend.log

The /usr/local/sbin/mpc-play is a script that manages the current MPD playlists. If it’s length ≤ 1 then it assumes we’re playing a stream. If the length > 1, then a list of MP3’s is assumed. This allows quick switching between a web stream (radio) and a list of MP3’s, and will even revert the play position.

#!/bin/sh

die () {
    echo >&2 "$@"
    exit 1
}

[ "$#" -eq 1 ] || die "1 argument required, $# provided"

#assume we are playing mp3 files if we have a playlist length >1
if [ `mpc playlist | wc -l` -gt 1 ]
then
        # playlist is longer than 1, we have music
        if [ "$1" = "music" ]
        then
                # we already are at state "music". Play the playlist.
                mpc play
        else
                # current playlist is music, we want to play a stream.
                # Save current playlist position
                mpc -f "[%position%]" | head -1 > /home/pi/lirc/playlistnumber
                # Save current playlist as music; clear playlist; load stream
                mpc save music || ( mpc rm music && mpc save music )
                mpc clear
                mpc load "$1"
                mpc play
        fi
else
        # playlist length is 1 or shorter, we are now in a stream or have an empty playlist
        if [ "$1" = "music" ]
        then
                # clear current playlist, load music, play
                mpc clear
                mpc load music
                # Resume playing at the existing playlist position
                mpc play `cat /home/pi/lirc/playlistnumber` || mpc play                                          
        else
                # clear current playlist, load stream 
                mpc clear
                mpc load "$1"
                mpc play
        fi
fi

I assigned a button to start kodi.
However, I would not start as user root.
I made a script /usr/local/sbin/kodi-start to run it as user pi (hat tip):

#!/bin/bash
mpc stop
runuser -l pi -c 'kodi-standalone & '

The mpc stop is so sound is stopped when starting kodi. Apparently both MPD and kodi “take hold” of the audio and can’t play at the same time.

Conclusion

Although installing this took multiple days of work, I was surprised at how easy it went and how little trouble I ran into.
I made the goal of having a full replacement for the MPDpi, which I shut down:

The raspberry Pi is now laying on top of my amplifier, which is not ideal, but I am amazed at the sound quality. Installing it in sucessive steps meant I could really hear the improvement of the new speakers, speaker cables (which I did not imagine a non-audiophile like me could hear), and the hifiberry over the built-in raspberry DAC (the difference was even noticable on the €9,97 3W speakers!).

Kodi works, but is not configured as I would like it yet.

The beamer also works (although it smelled after not having been used for three years). If possible, I would like it to spitch on and off automatically.

My bookcase looks a lot better now, but there is still a bare raspberry dangling in there. Also, I quicly tried installing scummvm (to play retro games) and that works.
What I would also like is stream audio and video from an android phone to the raspberry.

That will all come in a later blog post.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.