When a friend of mine showed the awesome little wooden Jukebox he made for his kids, I loved the idea, and knew I could make a similar contraption by recycling an old Raspberry Pi 1 I had on a shelve.
After I was finished I published build instructions on GitHub, along with the code I used, if someone wants to reproduce this. The article you are reading now is actually the story of the making of it.
First, I ordered some RFID cards and a USB connected card reader from Aliexpress, since the long delivery time would hold up the project:
This kind of card reader presents itself as a keyboard to the computer that is connected to it, so when scanning a card, the number printed on the card will be 'typed' into the computer by the reader.
True to the UNIX philosphy, playing the songs should be done with simple MP3 player application like mplayer or sox. That can run as a subprocess.
It turned out that there is a significant delay on the Raspberry Pi 1 before the music actually starts playing. So I ended up running the jukebox on a Pi 2 that was already sitting in the TV cabinet.
apt-get install sox libsox-fmt-mp3 alsamixer
Next I got to work in Python, and wrote a small script that would read the number typed, finds a file that starts with the number and, if found, it will start the MP3 player application.
import subprocess import sys, glob player = None while True: print("player ready:",) code = raw_input() for filename in glob.glob("*"): if not filename.startswith(code): #not the file we want, check next continue if player: #stop player if already playing player.terminate() player = None print("playing ", filename) player = subprocess.Popen(["play","-q", filename], stdin=subprocess.PIPE, stdout=sys.stdout,stderr=sys.stdout,bufsize=1)
I ended up extending the script with a 'lock' function that will disable/enable the player with a special card, and added a 'stop' card, to stop the playing song.
Next came the system integration. I didn't find an easy way to read the card reader from python, so instead, I replace the logon process on the raspberry pi with the script. Instead of getting asked a username and password to login, the pi instead waits for a card number to be typed in.
This is done by creating a systemd service file that starts the script on tty1:
[Unit] Description=play on tty1 [Service] Type=simple ExecStart=/usr/bin/python /home/pi/play.py ExecStop=/bin/kill -HUP $MAINPID StandardInput=tty StandardOutput=tty #StandardOutput=journal StandardError=journal WorkingDirectory=/home/pi TTYPath=/dev/tty1 Restart=always RestartSec=2 [Install] WantedBy=getty.target
We can install it, and enable this service file instead of the getty on tty1 like this:
sudo install -m 644 play.service /etc/systemd/system/play.service sudo systemctl daemon-reload sudo systemctl mask firstname.lastname@example.org sudo systemctl enable play.service sudo systemctl start play.service
After compiling a set of song MP3's that Arthur likes, I made labels with pictures representing the songs a bit. I finished off the label with adhesive vinyl (the one used with school books).
I also made a piece of paper with an musical notes on it and I laminated it. (you can find that in the artwork/ folder on the GitHub project)
I installed the RFID card reader using double sided tape behind the glass front of our TV furniture.
When the RFID reader outputs a card code, the player checks if a filename starting with the code (and a dash) exists. If found, it starts playing it.
There are two special cards:
- The "key" card: to unlock/lock the player
- The "stop" card: to stop playing the current song
To identify these special cards to the player, create empty files with the words key and stop. Next rename them to prefix them with the text generated by the RFID reader for those cards, just like is done with the MP3's.