A Raspberry Pi Subsonic Jukebox using Java 8

In the comments of my Install Subsonic media streaming server on a Raspberry Pi post, Ross very kindly posted some instructions on how to get the Jukebox mode of Subsonic working on the Raspberry Pi.

DevilWah also mentioned that a developer preview release of Java 8 is available which Ross tried and gave the thumbs up to.

This post has instructions of how to get Java 8 installed on your Raspberry Pi, how to get Subsonic working and then how to configure Jukebox mode so that you can play music from the headphone jack or HDMI port of the Raspberry Pi itself.

This post borrows heavily from instructions which are already available on the internet and from Ross’ instructions. I have conglomerated them here as it’s useful to have them all in one place.

I’ve only just completed this build but it does already seem quicker. I’m running the Java 8 Jukebox build on a second Raspberry Pi so will run it side by side with my original build for a while to do some direct comparisons.

Edit: the java 8 version uses a lot less CPU than the open jre used in the original instructions. I’ve just followed these same instructions and directly upgraded my original raspberry pi subsonic server to run on java 8. I have yet to test if the jukebox mode is working on that though.

I should mention that both Pis are the original versions with only 256MB RAM each. I’m running them headless so my only access is through SSH. I have seen a few of the CPU and memory spikes occur on the new Java 8 build in a similar way to the original build but they have not been as severe and have not lasted anywhere near as long. I can also confirm that the Jukebox mode is working as I’ve used it a lot!

 

So, without Further ado, on with the instructions.

The instructions I followed for installing Java 8 are here and here. Neither gave me the full instructions though so I’ve outlined what I did below.

Java 8 is the first version of the Oracle Java JRE which can run on the faster ‘Hard Float’ version of Debian Wheezy which is available on the Raspberry Pi download pages.

You first job is going to be to set up an SD Card with a fresh image of  Debian. This is explained best on the Raspberry Pi wiki.

Once you’ve booted into your Raspberry Pi via ssh for the first time you should run the config program

sudo raspi-config

The instructions at java.net say that the memory split should be 128MB, so that’s what I did.

The other instruction I followed from java.net which I don’t normally do was to uncomment the two lines in /boot/config.txt.

sudo nano /boot/config.txt
change
#framebuffer_width=1280
#framebuffer_height=720

to
framebuffer_width=1280
framebuffer_height=720

Next up is to download and install Java 8. Follow this link and highlight the radio button to say you accept the License Agreement (it’s standard ‘I promise you my first born’ stuff). Then right click the ‘Oracle JDK 8…’link and select ‘Copy link location’.

Back on your Pi enter wget and then right click on the ssh window and paste. Hit enter and you will start downloading Java 8.

Once it’s finished you need to make a new directory for the install

mkdir -p /opt and then unpack the file you just downloaded into that directory
sudo tar zxvf [file you just downloaded] -C /opt

You now need to tell the system that a new Java version is installed and that you want to use it as default with these commands

sudo update-alternatives --install "/usr/bin/java" "java" "/opt/jdk1.8.0/bin/java" 1
sudo update-alternatives --set java /opt/jdk1.8.0/bin/java

The system now knows where Java is installed but we will need to let subsonic know where to find it. To do this we update the JAVA_HOME environment variable which can be set in your environment file.

sudo nano /etc/environment and add the line
JAVA_HOME="/opt/jdk1.8.0"

You also need to point your bash console to the new environment variable.
nano ~/.bashrc add the lines
export JAVA_HOME="/opt/jdk1.8.0"
export PATH=$PATH:$JAVA_HOME/bin

Give your Pi a quick reboot and you’re all set to install subsonic.

Now we can set up the Jukebox mode so that you can plug your pi into your hi-fi and play music directly on the hardware.
You need to download the Debian .deb package of Subsonic from the Subsonic website
(right click the ‘direct link’ and select ‘copy link as’)

On your pi enter the following command
wget -O subsonic.deb [right click to enter the download url] to download the install package and then
sudo dpkg -i subsonic.deb to install it

We need to create a user for the subsonic process and add that user to the audio group so that jukebox will work
sudo adduser subsonic
sudo adduser subsonic audio

Update subsonic to use this user
sudo nano /etc/default/subsonic and change the last line to
SUBSONIC_USER=subsonic

So that subsonic can transcode correctly we install the correct versions of ffmpeg and lame
sudo apt-get install ffmpeg lame

We then add symbolic links to the subsonic transcode folder so that it uses these applications instead of the ones it comes bundled with (good suggestion Ross)
sudo ln -fs /usr/bin/ffmpeg /var/subsonic/transcode
sudo ln -fs /usr/bin/lame /var/subsonic/transcode

We now need to add a line to the coding of subsonic so that it knows that there is a soundcard on the pi and to use that as default
sudo nano /usr/bin/subsonic. find the line that says -verbose:gc \ and add the following line above it
-Djavax.sound.sampled.SourceDataLine=#ALSA \

The last step is to tell the pi which sound output to use. There is a variable in this next command. The last character is ?. You can change this to be one of three values depending on where you want the sound to come from. the available values are:
1 = 3.5mm jack
2 = HDMI port
3 = Default

sudo amixer -c 0 cset numid=3 ?

That’s it! give your pi a reboot and you should now be able to play music directly on your pi.

Add an external hard drive to a Subsonic Raspberry Pi server

Now that my Subsonic Raspberry Pi server is up and running, I wanted to add some media. My Pi is running with an 8Gb SD card but this is only enough for a few songs and ideally I would like my entire media collection available through Subsonic.

I had an old Terabyte external hard drive lying around which hasn’t worked for a while. A common cause of malfunction with an external hard drive is not with the hard drive itself but with the electronics in the caddy which communicate between the drive and the USB port.

I tested if this was what was going on with my drive by removing the hard drive from the case (read “smashed the case to bits, but gently”) and connected it to my desktop PC with a spare SATA cable. I fired up GParted (I’m running Ubuntu 12.04) and, luckily for me, I was able to see the drive as available. I was even able to get the old files off the drive which proved to me that the issue was with the caddy.

I decided that to get the best performance from my Subsonic Pi I should format the hard drive in one of the native Linux formats. I quickly decided on ext3 as it seems to give the best balance between stability and performance. (I decided this based pretty much on one blog post so I could well be completely wrong. All I know is that it is working well for me.)

To format the drive I used the mke2fs utility.

sudo mke2fs -L subsonic media -t ext3 /dev/sda1

The command above says “format the hard drive partition found at /dev/sda1. Use ext3 as the type of file system (-t) and give the new format the label of ‘subsonic media’ (-L)”. You will need to check the name of the partition you want to format first as it could be different from /dev/sda1.

The next job is to create a mount point so that we can easily access the files on the external hard drive once we’ve told the system where to find it.

sudo mkdir /media/subsonic

We also need to make sure that the mount point is owned by the user that the subsonic process is run by (in the first post I talked about creating a user to run subsonic for security).

sudo chown [subsonic user] /media/subsonic
sudo chgrp [subsonic user] /media/subsonic

Next we need to edit the fstab file. This file lists the devices which the system can mount. It is read at boot so by adding to it we can make the external drive accessible every time the Pi boots.
First of all I need to know the unique ID of the hard drive. To find this out I ran this command

sudo blkid

This will give an output similar to this

/dev/mmcblk0p1: SEC_TYPE="msdos" UUID="9DCF-4197" TYPE="vfat"
/dev/mmcblk0p2: UUID="f10ba0bd-17e0-4800-b0af-19bb2ed45acd" TYPE="ext4"
/dev/sda1: LABEL="subsonic media" UUID="8accdf5d-476-a240-1f4f645cc" TYPE="ext3"

The first two lines reference the Raspberry Pi’s SD Card so the one I’m after is the third. It should refer to the same partition you used in the mke2fs command as well as the label you set with it. The unique identifier is the long number after “UUID=”. If you highlight everything from “UUID=” to the end of the number and then right-click the ssh window, you can select ‘copy’ to save the number to the clipboard.

We then need to edit the fstab file. (I’m using vim as my editor here but you can use whatever is installed, which is nano by default)

sudo vim /etc/fstab

At the end of this file we need to add a new entry. The line should look like this

UUID="8accdf5d-476-a240-1f4f645cc"  /media/subsonic  ext3   defaults  0  0

The first part is the unique ID of the hard drive and the second is the mount point we set up just now. The third entry is the type of file system (as mentioned I used ext3) and the fourth, fifth and sixth entries should stay as ‘defaults’, ‘0’ and ‘0’. The entries should be separated by tabs so don’t copy the line above directly as I used two spaces.

Once you’ve edited and saved your fstab file you can ask the system to mount everything with this command

sudo mount -a

You won’t see a message to say that it’s worked but if you don’t see an error message it’s safe to say that it has. You now have a mounted hard drive which Subsonic can access and on which you can start to add your media.

Install Subsonic media streaming server on a Raspberry Pi

Edit: There are also instructions for building a Subsonic Raspberry Pi using Java 8 here. The main benefits of that method are a faster UI, better performance and the ability to use the Jukebox mode of Subsonic to play music through the headphone jack of the Pi itself rather than through the web interface.

Subsonic is great. It can play music and video of most formats through a web interface and there are apps available for most mobile platforms so you can take all your media with you anywhere.

I wanted to install Subsonic on a Raspberry Pi as it would give a low-cost and low power platform for my media streaming. Ideal!

Searching around the web there are a few mentions of Subsonic and Raspberry Pi but no clear instructions and certainly nothing that mentions some of the issues I found.

I started off with a clean Raspbian install on an 8GB SD card. If you want instructions for how to set this up, take a look at the Raspberry Pi wiki here. (At the time of writing the latest Raspbian image was dated 2012-08-16).

Once I’d booted the fresh Raspberry Pi and used ssh to log on my first step was to create a new user. This user will be running the Subsonic process so for security purposes I didn’t grant root access.

sudo adduser [subsonic_user]

Subsonic needs Java to run so I installed that next (these next few steps are detailed on the Subsonic website).

sudo apt-get install openjdk-6-jre

I then downloaded the subsonic .deb package with wget and installed it. I downloaded the latest beta version which at the time of writing was 4.7.beta3 but you can find the latest stable version or the latest beta version on the Subsonic download page. Make sure you follow the download links to SourceForge  until you see a ‘Direct Link’. Right click that link and select ‘Copy Link’. You can then right-click the ssh window to paste the URL there.

wget [right-click paste url] -O subsonic.deb
sudo dpkg -i subsonic.x.x.deb [downloaded file]

As the Subsonic page says, the user for the subsonic process should be changed for security.

sudo nano /etc/default/subsonic

Edit the SUBSONIC_USER line at the bottom.

SUBSONIC_USER=[subsonic_user we created earlier]

Save the file and restart the Subsonic process to make the changes.

sudo service subsonic restart

 

This is where I found my first issue.

I have a lot of music that is in FLAC format. In order to play music through the web interface, Subsonic transcodes the files from FLAC to mp3. To do this it uses a program called ffmpeg. The ffmpeg version which Subsonic installs by default doesn’t work correctly on the ARM architecture processor of the Raspberry Pi so in order for transcoding to work properly, I found that I needed to replace ffmpeg with an ARM compiled version.

Luckily this is really straight forward.

sudo apt-get install ffmpeg

This installs ffmpeg to the /usr/bin folder but Subsonic can’t use it from there so we need to copy it to the correct folder.

sudo rm /var/subsonic/transcode/ffmpeg
sudo cp /usr/bin/ffmpeg /var/subsonic/transcode

I repeated the above steps for the lame transcoder which Subsonic also uses. Just repeat the install, remove and copy steps but replace ‘ffmpeg’ with ‘lame’.

Edit: I recently had some trouble with the transcoding failing every now and again. Checking the ‘Transcoding’ section of the Subsonic settings revealed that some of the enabled transcodings were set to use ‘Audioffmpeg’.

I changed these to refer to ‘ffmpeg’ and the transcoding worked again.

You should now find that transcoding works properly on Subsonic. You can fire up Subsonic by opening a web browser and typing in http://[ip address of Raspberry Pi]:4040. If you log in and go to Settings>Network you can ask Subsonic to configure your router and give you a subsonic.org sub-domain so you can get access to your Raspberry Pi Subsonic server from anywhere.

I’d also recommend using the donate function as this is a great piece of software.