Void’s Vault

Knowledge source for efficiency.

Music Player With Buildroot and Raspberry Pi

This is a description of my first project using buildroot. Nothing spectacular, but since I encountered some issues, a solution is presented in this post.

I had a spare Raspberry Pi, and I wanted it to play some music as soon as it gets plugged on a wall. First and foremost, rpi-buildroot is a great repository where you’ll have all you need to have a booting Pi. You’ll need a couple of things to be set with a music player.

Once the repository is cloned, do a quick configuration:

1
2
make raspberrypi_defconfig
make menuconfig

Under “System configuration”, you’ll be able to set a root password, should you need to log it to debug or do anything. Otherwise, make sure that inside “Target packages”, you add every alsa-utils packages, mpg123 and alsa-lib libraries. You can then save your configuration.

The music playing scripts I had needs shuf, so I enabled it in busybox.

1
2
# edit package/busibox/busibox.config
CONFIG_SHUF=y

I also need to activate the raspberry’s sound card.

1
2
# edit package/rpi-firmware/config.txt
dtparam=audio=on

And then, I need some scripts that will start at boot to play music. The first one is a script that will be installed under /etc/init.d. S50 was chosen because I wanted it to start late in the boot process.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# S50-playmusic-daemon-service

#!/bin/sh

PATH=/sbin:/bin:/usr/bin
DAEMON="/usr/bin/playmusic-daemon"
test -f ${DAEMON} || exit 0

startdaemon(){
  echo -n "Starting ${DAEMON}: "
  modprobe snd-bcm2835 #This will wire up the sound card with alsa
  start-stop-daemon -b --start --quiet --exec ${DAEMON}
  echo "${DAEMON} started."
}

stopdaemon(){
  echo -n "Stopping ${DAEMON}: "
  start-stop-daemon --stop --quiet --exec ${DAEMON}
  echo "${DAEMON} stopped."
}

case "$1" in
  start)
      startdaemon
      ;;
  stop)
      stopdaemon
      ;;
  force-reload)
      stopdaemon
      startdaemon
      ;;
  restart)
      stopdaemon
      startdaemon
      ;;
  *)
      echo "Usage: $0 { start | stop | restart}" >&2
      exit 1
      ;;
esac

The other one is a daemon that will keep running as long a the system is running. When it detects a usb drive, it will mount it and start the music player near the mountpoint.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# playmusic-daemon

#!/bin/sh
set -e

PLAYER="/usr/bin/playmusic"

test -f ${PLAYER} || exit 1

while true; do
  if ! df | grep -q "/dev/sd"; then
      partitions="$(fdisk -l /dev/sd* | awk '/^\/dev\/sd/ {print $1}')"
      for partition in "$partitions"; do
          mountpoint="/media/$(basename $partition)"
          mkdir -p $mountpoint
          mount $partition $mountpoint
      done
  fi

  if ps -p $(pidof $(basename $PLAYER)); then
      sleep 10
  else
      $PLAYER /media
  fi
done

The last script is the music player in itself. Pretty basic stuff. Find the mp3 songs, shuffle them, and plays them.

1
2
3
4
5
6
7
8
9
10
# playmusic

#!/bin/sh

SEARCH_PATH="$1"

find $SEARCH_PATH -iname "*mp3" | shuf | while read song
do
  mpg123 "$song"
done

These three scripts were small, so there was no real need to create a buildroot package for that. I simply dropped these scripts under board/rapberrypi/playmusic and I edited the post-build.sh script that was sitting there with the following lines.

1
2
3
# install playmusic
cp $(dirname $0)/playmusic/playmusic* ${TARGET_DIR}/usr/bin/
cp $(dirname $0)/playmusic/S50-playmusic-daemon-service ${TARGET_DIR}/etc/init.d/

Finally, we only have to compile the buildroot image, and flash it on an SD card.

1
2
make
sudo ./board/raspberrypi/flashsdcard /dev/sdf

Video after the break.

Enjoy!