To share both music and announcements, party.io uses Play from Github. Play is an ’employee-powered iTunes-based client-driven distributed music server for your office’. Our company DJ (a big-hearted, chrome-plated hubot) manages Play and occasionally accepts submissions from the team.
Play syncs the company song queue, but a streaming audio server is still needed to stream what’s playing. There are products that do this; Nicecast is one.
While it’s a little more work, the outcome is the ability to stream system audio anywhere. This makes more scenarios possible and it requires less maintenance - there’s no requirement to add media files in advance or to configure any applications.
You’ll need the latest compiler installed, whether via XCode or the OSX Mountain Lion Command Line Tools installation at http://connect.apple.com/ (recommended if you don’t need all of XCode). You’ll need to be somewhat comfortable with working on the command line.
Make sure you have Homebrew installed. And make sure to run
brew update before beginning, and
brew doctor if anything goes wrong along the way.
Soundflower is an inter-application audio routing utility. Soundflower creates additional audio devices that bind to applications to send and receive audio. Soundflower also comes with a program called Soundflowerbed. It lets you listen to audio locally even while broadcasting, like a splitter. Here’s what the Soundflowerbed menu bar app looks like:
Download Soundflower here and install it. Homebrew doesn’t have a Soundflower formula AFAIK, but thankfully there’s nothing tricky to this installation.
Once you’ve restarted we’ll install the next component, Jack.
Jack is a professional quality audio tool that can also route audio between applications.
Jack had problems initially with Mac OSX 10.7.3+, but a beta version seems to have worked the bugs out. Neither the Homebrew formula nor the latest download on jackosx.com have the new code, but you can find it on the Jack-OSX Yahoo group.
There’s a link to the 0.90b8 beta package on this thread. Download and install it, restarting when necessary.
Next, start the Soundflowerbed app (in /Applications/Soundflower) and choose the ‘Audio Setup’ option from the menu bar icon it installs. This will launch the System Audio Midi Setup menu. Set both input and output to Soundflower (2ch), like in the image below. Also make sure the volume is up.
Now we can start Jack as follows:
➜ ~ jackdmp -d coreaudio jackdmp 1.9.9 Copyright 2001-2005 Paul Davis and others. Copyright 2004-2012 Grame. jackdmp comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions; see the file COPYING for details JACK server starting in realtime mode with priority 10 Input channel = 0 ==> JACK input port = 0 Input channel = 1 ==> JACK input port = 1 JACK output port = 0 ==> output channel = 0 JACK output port = 1 ==> output channel = 1 CoreAudio driver is running...
Jack will now be running and can pass audio from Soundflower into our next component, Darkice.
Darkice is a live audio streamer. In our setup, it’s responsible for encoding the audio from Jack (into MP3, Ogg Vorbis, et. al.) and sending it to Icecast.
We’ll install Darkice with Homebrew but this gets a little weird. Darkice has a dependency on Jack, but Homebrew doesn’t know we’ve already installed Jack through another means. So we have to install a ‘dummy’, unlinked Jack so Homebrew thinks the Jack dependency is satisfied but Darkice builds against the downloaded Jack and not the Homebrew Jack (this is essential).
Run this command:
brew install darkice --use-llvm #ignore the linking warnings for Jack - Darkice must complete without Jack linked!
During this process Jack will fail to link and issue a warning but the script will still continue. This is good, because Darkice will then build against the downloaded Jack. If things blow up which installing dependencies, install without the llvm flag and then retry this again. The goal is just to get the Jack-failed-link and the Darkice build in the same step.
Icecast is the web-serving layer of our stack, accepting incoming client connections and then broadacsting out the stream it receives from Darkice.
Install Icecast with Homebrew.
brew install icecast
Running Icecast and Darkice
We need a config file for Icecast: download this sample icecast.xml I’ve put together for this tutorial into
~/.icecast.xml. Now we can start Icecast:
icecast -c ~/.icecast.xml
We also need a config file for darkice: download this sample darkice.cfg into
~/.darkice.cfg. Once you have it saved, let’s start Darkice:
darkice -c ~/.darkice.cfg
We can now check our status by logging into Icecast’s administration UI. Go to http://localhost:8000/admin/ and enter the admin-user and admin-password from the icecast.xml config file. You should arrive at the admin page:
And you should see an area below that shows the active mount point, created by Darkice:
Testing with a client
Now, head over to another computer on your network, or your smartphone, and head for to the streaming address we’ve set up. The URL should look something like this:
Substitute ‘computer.local’ for the hostname or IP address of your computer. ‘spin’ is the name of the mountpoint we specified in darkice.cfg (and 8000 the port).
Paste the URL into Safari on Mac or iOS and you should get playback in iTunes / iOS Quicktime respectively:
Now you, your team, or the whole Internet can listen to your music, broadcasts, and the output of the command say! Flex the golden pipes!
Configure your router
You won’t be able to access your streaming server from outside your home network unless your open the appropriate ports on your router. In this example, you’d open port 8000. Your router’s instruction manual can you tell you how.
If you get it all to work, you might want to run these programs in the background and on startup. I wrote up a few basic plist files to be used with launchd that do just that. You can find them in this gist.
Thanks to the creators of all of these fine tools and the author of this article: Broadcasting music to multiple speakers.