Monday, August 04, 2014

Integrating Apple Airplay Functionality into a SqueezeBox on Mac OS X

I've wanted to integrate AirPlay functionality into my Squeezebox based home audio system since I first heard that Apple’s Airplay had been hacked.

After nearly a decade of constant use, my Squeezebox(es) have proven themselves to be the single-best technology purchases I've made. The extensibility of the platform and dedicated user community developing third party plugins and apps has kept the platform relevant despite being abandoned by corporate overlords at Logitech.

My interest in trying to get Airplay working with SlimServer (aka LMS) was rekindled this spring when I saw that the Squeezebox user community had hacked a way to integrate Shairplay functionality to Linux-based systems running LMS: http://forums.slimdevices.com/showthread.php?100379-Announce-ShairTunes-Plugin and slim user StuartUSA’s even went so far as to create a LMS plugin: https://github.com/StuartUSA/shairport_plugin

Given the Shairport hack that StuartUSA’s plugin is based on has a port for OS X and OS X is a UNIX-based operating system, I figured I could get the hack to work on my home server (an old 2GHz Core Duo 32-bit Macbook running OS X 10.6.8 Snow Leopard running LMS and Plex, among other things).

Only problem was I don't really have any experience with coding or working on the command line. That said, I've wanted to get a better understanding of coding, so I took it upon myself to figure out a solution. After a lot of trial and error--and even more googling, I finally got it working on my server.

To write this tutorial and better understand what I actually was doing, I did a second install on another Mac with a 64-bit x86 processor running OS X Mavericks and LMS 7.9.

For the uninitiated, below is a step-by-step guide to getting Shairplay to integrate with your SqueezeBoxes.

Remember, I'm a total rookie at this...  It worked for me--twice. But I make no guarantees and if you run into problems or bork your system, I'm probably not going to be able to offer a whole lot of help.

I’m sure that the code-savvy will be able out point out many errors and shortcuts. Feel free to leave any tips/corrections in the comments and I'll try to incorporate.

Here is the Step-by-Step Guide:

1. Go to the App Store and install Xcode

2. Once Xcode is installed, you need to install the Xcode command line tools: a) Open Xcode app. b) Click on Xcode > Open Developer Tools > More Developers Tools. That will take you to Downloads for Apple Developers web site. Use your AppStore Id to login. c) Download & Install Command Line Tools for your Mac OS X version.

A bit about working in Terminal... The dollar sign ($) is the start of a command line to copy and signifies a new line, don't copy it into Terminal. You'll also notice the sharp (#) in some lines. # isn’t code and signifies notes—all text to the right of the # are notes. Hit [Enter] after each string of text is pasted to execute the command.

3. As I’m not that comfortable in Terminal, I use Finder in conjunction with Terminal as I find it easier to find, move, and rename files in the Finder GUI. I find it easiest to keep Finder and Terminal windows open side-by-side so you can easily move back and forth.

In OS X, a lot of components of LMS are installed in hidden folders and we need to modify some of those hidden files. To do so easily in Finder, we need to make hidden files visible. There is no longer an easy preference toggle to do this in Mavericks and we need to use Terminal:
$ defaults write com.apple.finder AppleShowAllFiles TRUE
$ Killall Finder
This will restart Finder with all the hidden files now visible in light grey text.

4. Install Homebrew to enable Linux package management support on OSX: a) Open Terminal
b) Paste the following code at the prompt:
$ ruby -e “$(curl -fsSLhttps://raw.github.com/Homebrew/homebrew/go/install)” 
Once installed, make sure the brew packages are up to date by typing in Terminal:
$ brew update 
5. Now we need to install the dependencies that are needed to run the shairport plugin. At the Terminal command prompt type:
$ export ARCHFLAGS=”-arch x86_64” # this sets the compiler to build all the modules for Intel x86 64bit processor
$ curl -L http://xrl.us/installperlosx | bash # while perl is already installed with OS X, this updates to the latest version and makes sure dependencies are in order
$ brew install pkg-config libao
$ sudo perl -MCPAN -e ‘install Crypt::OpenSSL::RSA’ # choose auto configuration
$ sudo perl -MCPAN -e ‘install IO::Socket::INET6’
$ sudo perl -MCPAN -e ‘install Net::SDP’
6. With dependencies now installed and hidden files visible, we need to install the LMS Shairport plugin. The issue is the plugin posted on the github repo has Linux defined as its target platform, so it crashes if you use the install and enable the plugin using the normal LMS interface. The tricky part here is we have to add the plugin repo and enable it, but then we have to delete the line of code in the BEFORE restarting LMS and having the install complete.

a) Scroll to the Additional Repositories at the bottom of the Plugins page in the LMS web interface, and add the repo: http://raw.github.com/StuartUSA/shairport_plugin/master/public.xml then Apply changes.

b) Scroll down, Enable the ShairTunes Plugin, then Apply changes.

c) A dialog window will pop-up asking if you want to Restart the server. DO NOT RESTART THE SERVER! Click the Restart Later button. If you restart the server, you will need to delete the misinstalled plugin, repo, and restart LMS a few times. Trust me. Don't restart it now. Took me forever to figure out what was going on.

d) Now, with the plugin install mid-stream, we need to modify the ShairTunes.zip file that LMS just downloaded. On my install it is in the hidden directory at:
/Users/YourUserName/Library/Caches/Squeezebox/DownloadedPlugins/ShairTunes.zip
Using Finder, navigate to the ShairTunes.zip file (I couldn’t find it using a Spotlight search, as it’s in the hidden Library folder).

e) Extract the zip. In the ShairTunes folder that is extracted, open the install.xml file with TextEdit (right-click, open with...). The last line of code notes instructs the LMS installer the target platform is Linux:
<target platform>Linux<target platform>
Delete that line of code and then Save the install.xml file.

f) We now need to delete the old ShairTunes.zip and Compress the ShairTunes folder with the modded code into a new .zip (Right-click on folder, Compress ShairTunes), you can then delete the ShairTunes folder so that all that’s left in the DownloadedPlugins folder is the modded ShairTunes.zip.

g) Restart your LMS. If you’re watching the DownloadedPlugins folder in Finder, ShairTunes.zip should disappear and now be installed in the …/InstalledPlugins/Plugins/ShairTunes/ folder. ShairTunes should now appear as an Active Plugin in the LMS Plugins Settings & you should see AirPlay instances for all your SqueezeBoxes on iOS devices and in iTunes. They won’t work yet, but we're getting there.

7. With the ShairTunes plugin now running on LMS and Airplay instances appearing on iOS devices, we need to install the shairport_helper into the systems PATH to get the plugin functioning. To do so we need a version of the shairport_helper compiled for our architecture (Intel 64-bit OS X). You can either download a precompiled version, which is a far simpler route or compile your own.

Link to precompiled OS X 32 & 64 bit helpers: https://db.tt/XaMijjxb

If you go the precompiled route, change the appropriate file name to shairport_helper and skip to Step 8.

To compile the OS X executable we need to head back to Finder and Terminal:

a) Using Finder, navigate to the …/shairport_helper/src/ folder on my machine it’s at:
/Users/YourUserName/Library/Caches/Squeezebox/InstalledPlugins/Plugins/ShairTunes/shairport_helper/src
Once there, delete the two Linux object files that are in that folder ( alac.o & http.o).

b) Now switch over to Terminal. We need to change into the .../src/ folder directory. The Unix command to change directory is cd and the easiest way to get the full file path on OS X is to drag the folder from Finder over to Terminal window. So, in Terminal type: cd [space] then drag the file over for the full path. It should look like this:
$cd/Users/TheMac/Library/Caches/Squeezebox/InstalledPlugins/Plugins/ShairTunes/shairport_helper/src
You should now be in the src directory, it will look as follows:
ComputerName:src YourUserName$
c) Now to compile the shairport_helper.  In Terminal at the src directory type:
$ make
You should see 4 warnings about deprecated keys and unused variables, you can ignore them.

d) Switch back over to Finder and inside the …/src/ folder you should now see a file named shairtunes_helper that is a Unix executable. That is our freshly complied helper.

8. Now all we need to do is copy shairtunes_helper to the right PATH and we’re good to go! If you downloaded the precompiled version you need to rename the file “shairtunes_helper”
In Finder, copy shairtunes_helper to /usr/local/bin

9. Restart your LMS and you should see Airplay instances for your Squeezeboxes in iTunes and iOS. Select and then try to play something to them. If you aren't getting any sound it could be because of an iOS bug with IPv6 and Shairport. Turning off IPv6 on your server solves the problem.

Note: disabling IPv6 could have unintended consequences, like rendering AirDrop sharing unusable. I don't use AirDrop, but haven't noticed any other issues thus far.  You can turn off IPv6 in Terminal with:
$ networksetup -setv6off Ethernet && networksetup -setv6off Wi-Fi
10. To re-hide the hidden files in Finder, in Terminal type:
$ defaults write com.apple.finder AppleShowAllFiles FALSE
$ Killall Finder
Should you want to turn IPv6 back on you can go through System Preference>Network>Advanced>TCP/IP and toggle on and off or in Terminal:
$ networksetup -setv6automatic Wi-Fi && networksetup -setv6automatic Ethernet
That should be it! Enjoy!