How to Build a Jukebox With a Raspberry Pi

This is a guide I wrote to remind myself how to build an always-on jukebox - just like those old timey jukeboxes, but instead of putting in a coin and pressing big buttons, 1. you control it with your phone and 2. you have an unlimited selection of music. Just type in the name of any song (any song!), and the little machine should start playing it within a few seconds.

The goal here is to build something super easy to use, so everyone in your home or office or whatever can participate with any broken crappy phone they have, as long as it has a web browser. There are no usernames, no passwords, no apps. You don't even need to maintain a music library - the jukebox just goes out on the internet, and streams whatever it can find.

The final jukebox, nestled among the narwhals:

Control it from your phone or computer or anything with a web browser. Search for any song you can think of. A few seconds later, it'll get added to the playlist.

Tap to switch songs, remove a song, etc. But only a monster would remove any of these great tracks.

Materials

Here's what you'll need to set up your own jukebox on a Raspberry Pi.

Install All the Software Tools

  1. Install the operating system. Download the Raspberry Pi Foundation's official Raspberry Pi OS and follow their instructions to write it to your SD card. They have several versions available. I used the "...with desktop" version, but the more minimal version with no graphical desktop "...lite" should work too.

  2. If you have an extra USB keyboard, mouse, and monitor, plug them in now. Otherwise, you'll need to set up your Pi in "headless mode" - which means you connect the Pi to you network and control it remotely from another computer. Here's how to do that.

  3. Turn on the Pi. There's no on switch, so just plug it in and the little device will come alive. If you're in headless mode, now's the time to SSH in. The default username/password is pi/raspberry.

  4. Make sure everthing is up to date. Run these commands in the terminal.

    sudo apt -y update
    sudo apt -y full-upgrade
  5. Setup some basic Raspberry Pi settings. Run this command in the terminal and change a few options:

    sudo raspi-config
    • Change your password, if you want.

    • Change the hostname of your Pi that will be visible on your network. I named mine "JKBOX".

    • Advanced -> Expand Filesystem. When you initially write the OS image to your disk, it may have left a bunch of unusable space at the end of the drive. This frees it up and makes it available to you.

    • Advanced -> Audio: Select which audio interface to use. I'm using the analog "headphones" jack.

    • Anything else you want to experiment with. If you break your computer, it's only $35!

  6. Install some packages we'll need.

    sudo apt -y install alsa-base alsa-utils
    sudo apt -y install ffmpeg
    sudo apt -y install mpd mpc
    sudo apt -y install apache2 php libapache2-mod-php
    sudo apt -y purge pulseaudio

    It's not required to know this stuff, but I'm always lost and confused when instructions on the internet make me type in lots of commands without telling me why or what they do. So if you're curious: alsa is some sort of framework for playing audio on linux. We also remove pulseaudio if it happens to be installed, since I've read it can conflict with alsa. ffmpeg is a tool to help process video and audio. mpd is the program that will actually play the audio and maintain a playlist. mpc is a command line tool to control mpd. apache2 is a web server, and the thing our phones and computers will connect to, to control the jukebox. php is a scripting language that runs inside of apache.

  7. Clean up the apt system. This isn't strictly necessary, but clutter isn't healthy for anyone.

    sudo apt -y autoremove
    sudo apt -y clean
  8. Install youtube-dl. This is the magic tool that searches and downloads videos from youtube and many other sites. This fantastic tool is the reason our jukebox has access to pretty much any song ever recorded. We install it manually to ensure we get the most up to date version. Software on the apt repository is often out of date.

    sudo wget https://yt-dl.org/latest/youtube-dl -O /usr/local/bin/youtube-dl
    sudo chmod a+x /usr/local/bin/youtube-dl
    
    # Optional test that it works.
    # This should download a video to your current directory:
    youtube-dl https://www.youtube.com/watch?v=bWcASV2sey0
  9. Install the jkbox script. This is the little script I wrote that acts as the duct tape that connects all the above tools together. When you connect to the jukebox with your device, this script works its magic behind the scenes: It tells youtube-dl to search and download. It tells mpc to tell mpd to play particular tracks, or change the volume. It queries the mpd playlist. It deletes old tracks. It also contains the webpage that you see when you access the jukebox from your web browser. But you don't need to know any of this, it should all just work.

    wget https://kylegabler.com/assets/jkbox/jkbox.zip -O /tmp/jkbox.zip && unzip -o /tmp/jkbox.zip -d ~/jkbox && rm -rf /tmp/jkbox* && chmod -R 777 ~/jkbox && echo "SUCCESS"

    Note that this command dumps the script stuff into your home directory in this location: ~/jkbox, which is just an abbreviated way of saying /home/pi/jkbox. (This tutorial assumes you are using the default "pi" user.) Look around in that directory if you're curious how the script works!

Give Your Pi a Permanent Address

Next, we need to make sure your Pi always has the same address so you can bookmark it and then forget about it forever. Without this step, the Pi will potentially receive a new and different address from your router every time it's powered on, and it won't be easily accessible from your other various devices.

  1. Log into your router. I can access my router by typing 192.168.1.1 into a web browser. Yours might be different, so ask the internet for help with your specific model if needed.

  2. Find the DHCP settings. This is where you can change how your router assigns addresses to the various devices you connect to it. All routers have different interfaces, but the general idea is the same. This is what the DHCP section of my router looks like:

  3. Tell your router to always give your Pi the same address. Poke around in the router settings to find the "MAC address" of the Pi. Mine was listed under the "DHCP clients" tab, "b8:27: blah blah blah". In the "DHCP Reservation" area, add an entry to always associate whatever IP address you want with your Pi's MAC address. I chose "192.168.1.210" for mine. Whatever you choose, REMEMBER IT! You can also see I have two other Raspberry Pi's listed in this section as well. (Spoilers for other projects.) If you're totally lost, just do an internet search for something like dhcp assign static ip your-router-make-n-model. Reboot your Pi to begin fresh with your brand new permanent address.

    sudo reboot

Set Up the Various Software Tools

At this point, all the software we need is installed, and we have a permanent address. Now we just need to configure a few of the tools.

  1. Set ALSA volume. There are multiple places to set volume - 1. in software, 2. your sound chip's hardware, 3. your physical speaker volume knob, and probably more. We'll eliminate one of these by just setting it to 100% and forgetting about it forever.

    alsamixer
    
    # 1. Select the audio output you will be using with F6. I'm using the "headphone" jack.
    # 2. Tap the up arrow key until the volume gets to 100%.
    # 3. Press Esc to quit.
  2. Set up MPD (the thing that plays your music). Edit mpd's config file using nano.

    sudo nano /etc/mpd.conf
    1. A few lines from the top, set music_directory to /home/pi/jkbox/tracks. This is the temporary location where audio files will appear while playing them.

    2. Near the top of the file, it doesn't really matter where, add the following lines. volume_normalization will try and keep the volume of all music about the same so you don't have to constantly tweak your volume knob. samplerate_converter will select the highest quality sample rate converter.

      volume_normalization "yes"
      samplerate_converter "0"
    3. Scroll way down to the "Audio Output" section. Find the "audio_output" where the type is "alsa" and make a few modifications so it effectively says the following. Double check that none of these lines are commented out - just remove the "#" at the beginning of their lines.

      audio_output {
      type            "alsa"
      name            "My ALSA Device"
      mixer_type      "software"
      buffer_time     "50000"
      }

      (Update: This tutorial now uses the "software" mixer instead of the default "hardware" mixer for controlling volume. A recent update resulted in mpd being unable to change the hardware mixer, and I have no idea why. If anyone knows what's going on here, please let me know!)

    4. Ctrl+x to save and exit.

    5. Restart the mpd service.

      sudo systemctl restart mpd
  3. Set up apache. This is the web server. For reference, apache's config file is at /etc/apache2/apache2.conf, but no changes are required. You can actually open a web browser right now and type in the address of your Pi, for example http://192.168.1.210 and a default Apache2 welcome page should appear.

    Apache's default web root is at /var/www/html/, but we want to serve content from that ~/jkbox folder we created in our home directory. So add a symlink to point from this default web root to your new jkbox dir.

    sudo chmod 777 /var/www/html
    ln -s /home/pi/jkbox /var/www/html/jkbox

    Restart the apache2 service. This probably isn't necessary, but it doesn't hurt either. I'm a Windows user. I like restarting things.

    sudo systemctl restart apache2
  4. Optional: Tell the Pi to keep itself up to date. We'll create a cron job to do this. You can edit your cron jobs with this command:

    crontab -e

    If this is your first time using crontab, the above command might ask you to select an editor. Choose nano. Once it opens, add the following line to the bottom:

    30 23 * * * /home/pi/jkbox/update.sh

    This cron job says "Every night at 11:30PM, run this little update script." Ctrl+x to save and exit. You can verify that the cron job was added with the command:

    crontab -l

    If you're curious what goes on during updating, just open up that .sh file and see for yourself. Note: You don't actually need to keep your pi up to date, and it may even be more stable if you don't. This will also download any updates to the script that I wrote, so you'd need to trust that I'm not running bad stuff on your pi or your local network. (I'm not, but still you shouldn't trust some random person on the internet.)

All done!

Ok ready! On your phone or computer, open a web browser and type in, for example, http://192.168.1.210/jkbox/ or whatever address you selected, and you should see a little interface for controlling your jukebox. Try typing the name of a song into the search box and see if it works.

My "hello world" song while building this was Toni Braxton's Un-Break My Heart, of course, so I recommend you type that in as your first song too. Also don't forget to plug in your speakers.

Now, next time you have friends or family over, you can give them that link above and enjoy a chaotic evening with your very own jukebox. Remember, they need to be connected to your WiFi - this won't work from outside your network.

Fun fact, your browser can save a bookmark to your phone's home screen for fast access. We did this on each of our family members' phones, so we can all easily fight over the music and volume levels. Have fun and if you build it, let me know how it goes!

FAQ

Is it secure?

Maybe don't store your bank records on this thing. I just wanted to let my family play Christmas songs. Probably best to keep it safely on your local network and don't let strangers from the internet get into it.

But wait, it's streaming any song from the internet? How does that even work?

It's basically just playing youtube videos, but without the video portion, only the audio. Kind of like if you go browsing youtube with your eyes closed. I was going to add additional freely available sources, but this seemed good enough for now.

Help, I followed your instructions and my house burned down.

Yes, this has all been a clever augmented reality advertising campaign for a game you might enjoy.

Well actually your Javascript is terrible.

Please, tell me more, Javascript enthusiast.

There's not even a PAUSE or STOP button. Wtf.

This is hisorically accurate. Real jukeboxes also didn't have pause buttons.

That's not true. Real jukeboxes absolutely had a way to stop the music. Also you spelled "historically" wrong.

Yeah ok, hisorically, I just never implemented a stop or pause button, but it was functional enough I never went back and changed it. If we want to stop the music over here in our house, we either turn the volume to zero or delete the songs from the playlist.

Help! It's not working! What are some things I can try?

  1. Check that youtube-dl works. This command should download a video to your current directory.

    youtube-dl https://www.youtube.com/watch?v=bWcASV2sey0
  2. Check that the music player is working. Music is played by a program called "mpd", controlled by "mpc". Copy some mp3's or whatever audio files into your ~/jkbox/tracks directory.

    # List all the songs mpd knows about. This should show anything in your ~/tracks folder:
    mpc listall
    
    # Display some other stats:
    mpc stats

    If the above fails, it means your mpc/mpd are not set up correctly. Double check that you edited the mpd config file correctly. If the above look ok, try some more things. (This is similar to what the website is doing behind the scenes.)

    # Add all tracks to the playlist.
    mpc add /
    
    # Play the playlist, starting from the first track.
    mpc play 1
    
    # Clear the playlist.
    mpc clear
    
    # Set volume to 40%.
    mpc volume 40
    
    # Check what else you can do with mpc.
    man mpc
  3. Double check your Pi is using the correct output. Run sudo raspi-config. Advanced -> Audio: Select which audio interface to use. I'm using the analog "headphones" jack.

  4. Make sure your speakers are turned on, connected, and volume knob is not at zero.

  5. Do a speaker test. List your audio output devices with command aplay -l. Take note of the card number of the device you want to use. Mine says card 0: Headphones [bcm2835 Headphones] blah blah blah, so I'm looking for card 0. Run a speaker test with command speaker-test -c2 -twav -l7 -D plughw:0,0, where the first number after plughw is the card number you want to use.

  6. It's possible something else is failing. Check the debug response from your Pi's web server. Open the jkbox site in Firefox on your computer. With the site open, press ctrl+shift+k to open Firefox's development console. Search for a song in the UI, and you should see a bunch of info about the request come through, as pictured below. Check the "debug" field for more helpful info on what might be wrong.

Which version of Total Eclipse of the Heart is better, the Bonnie Tyler version or the Nicki French version?

This could take many hours of careful listening and research to determine.

< back
(c) Kyle Gabler. All Rights Reserved. Terms and Conditions: By using this site, you agree that everything that was once yours is now mine, in perpetuity, throughout the universe. Enjoy.