Automatically connect to Airfoil Speakers

Update: In one of those embarrassing “You know there is a checkbox for that!?” moments, @rogueamoeba points out there is in fact a checkbox for this under Preferences “Automatically Transmit To:”


Airfoil from Rogue Amoeba is a wonderful application that allows you to stream audio from your computer to any device that will receive Airplay audio or run the Airfoil Speaker application. This includes all iOS devices. I use it stream audio to any room I may be in where I just hook an iPod touch or the iPhone up to the stereo.

The one drawback is the UI, which only allows to the devices to stream to on the Mac that is streaming. So I’ll be in the kitchen, where a 1G iPod touch is permanently hooked up to some speakers, turn on the iPod touch, start the Airfoil speakers app, then walk to the Mac in the living room, select the iPod touch in the Kitchen and walk back to enjoy the music. Wouldn’t it be great if Airfoil automatically picked up the iPod when it appears in the list?

Luckily Airfoil has AppleScript support. It is actually very easy. I have named all my iOS device to start with either “iPhone”, “iPad” or “iPod touch” so I can make Airfoil connect to all devices that are running the Airfoil app with

tell application "Airfoil"
    connect to every speaker whose name starts with "iP"
end

Now we need to keep running this command periodically in the background. I could setup a launchd plist for that, but AppleScript provides a simpler solution. Scripts that are saved as “Stay Open Applications” have an idle handler that is called after a certain number of seconds. See the details at the AppleScript Language Guide here.

So we wrap the command in an idle handler and add some checking to see if Airfoil is running so we don’t force launch Airfoil:

property idleTime : 30 -- in seconds

on run
	idle -- call idle on launch
end run

on idle
	tell application "System Events"
		if exists application process "Airfoil" then -- check if Airfoil is running
			tell application "Airfoil"
				connect to (every speaker whose name starts with "iP" and connected is false)
			end tell
		else -- if Airfoil is not running script can quit, too
			tell me to quit
		end if
	end tell
	
	return idleTime
end idle

The value returned from the idle handler is the time (in seconds) until it gets called again. This will leave other speakers (that don’t start with “iP”) such as the local speakers and any Airport Express speakers unaffected.

Save this as an application and make sure to select the “Stay Open” option. Then find the application and double click to launch. Start and quit Airfoil speakers app on your iOS devices and listen to Airfoil connect automatically.