http://confoundedtech.blogspot.co.uk/2018/01/linux-firewall-settings-for-apple.html
This post focuses on playing music from iTunes or iOS devices to a Logitech Squeezebox using AirPlay. The concept is to stream music from iTunes or iOS devices > Ubuntu server > Squeezebox. This requires three key tools Shairport, WaveInput, ecasound and some patience.
Shairport authored by James Laird in 2011 emulates an AirPort Express for the purpose of streaming music from iTunes and compatible iPods. It implements a server for the Apple RAOP protocol, it does not support AirPlay v2 (video and photo streaming). It is a reverse engineer of the RAOP protocol and relies upon the ALAC decoder released by David Hammerton, which is reproduced within Shairport. The project can be found at https://github.com/albertz/shairport
WaveInput authored by BPA is a Logitech Squeezebox plugin that enables PC audio to be captured and played through a Squeezebox. There are version of Windows and Linux and the project can be found here http://code.google.com/p/bpaplugins/
ecasound is a multitrack processing tool for playback, recording, format conversions, effects and mixing. Its use here is to transcode the raw stream from Airplay/Shairport into a format the Squeezebox can understand. I use it to introduce some LAME MP3 compression to the stream to help with my network bandwidth and to reduce playback stutter.
This article relies heavily upon the excellent work of Stuart Shelton and this post on the Logitech forums. There are two main methods for transferring the sound from shairport to the squeezebox:
The first relies upon piping the shairport stream to a raw data pipe which is then encoded to the Logitech Media server; and
The second uses a loopback device whereby shairport outputs audio to a loopback device which then feeds into the encoder for Logitech media server.
I'll discuss both methods here but will start with the raw pipe method since it is a lot easier to set up (although I am experiencing some performance issues with this approach on my Atom based server.
Shairplay to Raw pipe approach
The flow of music is:
iTunes / iOS
> via Airplay
> Shairport on Ubuntu
> raw date pipe
> ecasound on Ubuntu (to transcode the raw Airplay stream to compressed FLAC, MP3 or raw PCM)
> PCM stream (my server was not powerful enough for real time FLAC / MP3 encoding)
> WaveInput plugin on the Logitech Media Server (running on Ubuntu)
> via wi-fi or ethernet
> Squeezebox
> speakers
I hope the above helps someone, it certainly helped me.
Note Shairport requires that Bonjour / Avahi service that advertises the Airplay service to iTunes / the iOS device is already setup and configured on your Ubuntu server. It was already configured on my server from a previous effort at setting up an Apple Time Machine server you can read about setting up Avahi here from post 6 onwards. I won't be setting up Avahi in this post.
Here's how I got Airplay working:
1. Login into the Logitech Media Server ("LMS" or squeezeboxserver) via a browser at http://serverIP:9000/
2. Goto Settings > Plugins > At the bottom under "Additional repositories" add http://bpaplugins.googlecode.com/svn/trunk/repo.xml
3. Once the repository has been added under the 3rd party plugin section above enable "WaveInput (v1.04)" by bpa
4. Add a new favourite to the Squeezebox via LMS
Title: Squeezebox Airplay
URL: wavin:default
On the Ubuntu server (running 10.04 LTS)
1. Install the prerequisites for Shairport and WaveInput
apt-get install build-essential libssl-dev libcrypt-openssl-rsa-perl libao-dev libio-socket-inet6-perl libwww-perl avahi-utils pkg-config ecasound
2. Install the additional required perl packages
sudo perl -MCPAN -e 'install Crypt::OpenSSL::RSA'
sudo perl -MCPAN -e 'install HTTP::Message'
sudo perl -MCPAN -e 'install IO::Socket::INET6'
sudo perl -MCPAN -e 'install IO::Socket::SSL'
sudo perl -MCPAN -e 'install Net::SDP'
3. Install Shairport to the bin directory
cd /usr/bin
4. Download the source code
sudo git clone https://github.com/albertz/shairport.git
5. Change directory to the source code directory
cd shairport
6. Build the Shairport perl executable
sudo make
7. Create the pipe for shairport to pipe the music to WaveInput
sudo mkfifo /var/lib/squeezeboxserver/airplay-fifo.raw
8. Make the pipe accessible by the squeezeboxserver user (which will run shairport and LMS)
sudo chown squeezeboxserver /var/lib/squeezeboxserver/airplay-fifo.raw
sudo chmod 755 /var/lib/squeezeboxserver/airplay-fifo.raw
9. Adjust the firewall, forgive me I use ufw
sudo ufw allow from any to any port 5000:5005 proto tcp
sudo ufw allow from any to any port 6000:6005 proto udp
10. Move the WaveInput plugin settings from the cache to a more permanent place
sudo mv /var/lib/squeezeboxserver/cache/InstalledPlugins/Plugins/WaveInput /var/lib/squeezeboxserver/Plugins/WaveInput
11. Backup the default 'arecord' configuration for WaveInput
cd /var/lib/squeezeboxserver/Plugins/WaveInput
sudo mv custom-convert.conf custom-convert.conf.bak
12. Create a new configuration for WaveInput using ecasound,
sudo touch custom-convert.conf
sudo gedit custom-convert.conf
The config is as follows, the tab indentation is important:
#
# wavin
#
wavin pcm * *
# R
[ecasound] -q -z:db -b:4096 -f:16,2,44100 -i /var/lib/squeezeboxserver/airplay-fifo.raw -o stdout
wavin mp3 * *
# RB:{BITRATE=-B %B}
[ecasound] -q -z:db -b:4096 -f:16,2,44100 -i /var/lib/squeezeboxserver/airplay-fifo.raw -o stdout | [lame] --silent -r -q $QUALITY$ -v $BITRATE$ - -
wavin flc * *
# R
[ecasound] -q -z:db -b:4096 -f:16,2,44100 -i /var/lib/squeezeboxserver/airplay-fifo.raw -o stdout | [flac] -cs --totally-silent --endian=little --channels=2 --sign=signed --bps=16 --sample-rate=44100 --compression-level-0 -
Save the config!
13. In Squeezebox Server’s web user-interface, create a new Favourite named “AirPlay” with URL “wavin:default” (note the spelling i.e. no 'e').
14. Restart Logitech Media Server
sudo /etc/init.d/logitechmediaserver restart
15. Add the squeezeboxserver to the audio user group, this can be helpful for debugging the config
sudo usermod -a -G audio squeezeboxserver
16. Start the Shairport server:
sudo -u squeezeboxserver perl shairport.pl -v -a "Squeezebox Airplay" --pipe=/var/lib/squeezeboxserver/airplay-fifo.raw
17. On iTunes or iOS select the "Squeezebox Airplay" option and start playing your music.
If you cannot connect it is likely a firewall issue try disabling the firewall for debugging with sudo ufw disable - don't forget to re-enable it and don't do this if you connect direct to the internet without a router inbetween you and the internet.
18. In the Shairport terminal window you should see activity as the music stream is received, it's usual to see lots of errors since you are streaming most likely over wi-fi there are bound to be sync errors, such as:
"requesting resend on 1 packets"
"Suspected resync request packet received. Initiating resync."
"missing frame" etc.
Ignore them!
19. On LMS or the Squeezebox start playing the "Squeezebox Airplay" favourite after a couple of seconds you should have audio from your Squeezebox.
20. By default Shairport will stream FLAC to the Squeezebox, unfortunately my Ubuntu server doesn't seem to have the power (Atom D330) to encode the Airplay stream to FLAC for the Squeezebox on the fly in real time. This results in a very choppy sound experience with my audio playing for a couple of seconds then drops out for 30sec to a couple of minutes before playing another couple of seconds and the cycle repeats. I isolated this by testing the Squeezebox on wired ethernet so the only bottleneck could be the Ubuntu server. To combat this I disabled both FLAC and MP3 streams on the Squeezebox and used the raw PCM signal which does not require the Airplay stream to be transcoded.
Disable the FLAC and MP3 streams via LMS > Settings > Advanced > File Types > WavInput and set both eacsound/FLAC and eacsound/MP3 to disabled. Note do not touch WAV or Wavpack they are unrelated.
21. Restart LMS for the change to take affect
sudo /etc/init.d/logitechmediaserver restart
And start the Squeezebox playing back the "Airplay Squeezebox favourite"
This lead to a stable stream to my Squeezbeox using wired ethernet. Note it takes around 1 minute for the stream to settle down after play is hit on the Squeezebox there is some buffering/stuttering in the first 1 minute or so. It's also worth noting , the stream also has around a 30 second delay from the Airplay source.
22. Once I swapped back to w-fi I was plagued with choppy playback again. The only cause for this can be that my 54g wireless network does not have the bandwidth to both receive the Airplay music over wi-fi and stream it back to the Squeezebox over wi-fi. To combat this enabled the MP3 stream on the Squeezebox which takes preference over PCM.
Enable MP3 via LMS > Settings > Advanced > File Types > WavInput and set eacsound/MP3 to enabled. Again note not to touch WAV or Wavpack.
23. Restart LMS for the change to take affect
sudo /etc/init.d/logitechmediaserver restart
And start the Squeezebox playing back the "Airplay Squeezebox favourite".
Once again this lead to the a stable stream to my Squeezbeox with the same caveat that it takes around 1 minute for the stream to settle down after hitting play, there is still some buffering/stuttering in the first 1 minute or so; and the stream still has around a 30 second delay from the Airplay source.
Troubleshooting ideas
1. IPv6 If you experience issues try disabling IPv6 this did not effect me but to disable it edit /etc/sysctl.conf and add the following lines:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
2. Test shairport: Test the shairport connection to the Ubuntu server, this helps to isolate ecasound and the Squeezebox from the equation. Turn on your speakers and check they work by playing an audio file locally from Banshee or Rhythmbox or alike. Then fire up shairport using the command belw to output to alsa. This should give you sound once you play the Airplay source to shairport - if not you have problems with shairport.
sudo perl shairport.pl -v -a "Squeezebox Airplay" --ao_driver alsa
3. Test the pipe and ecasound: Ecasound transcodes the raw Airplay stream to FLAC, MP3 or PCM for the Squeezebox. The format used depends on the filetype enabled in the LMS settings. To test that the pipe is accessible (i.e. not a privilege issue) and that ecasound is working you can ask ecasound to output to the Ubuntu server's alsa interface to check for audio. Again test your Ubuntu servers speakers are working first with Rythmbox or Banshee or alike. Note your hardware interface may not be 0:1, I tried several combinations before I hit on the right interface.
sudo ecasound -i /var/lib/squeezeboxserver/airplay-fifo.raw -o alsa,hw,0:1
If you don't have sound on the server you can pipe the signal to xxd, whereby you should see the signal as an ascii stream in the terminal. If nothing is moving and there's no activity then there's a problem with the pipe (check the permissions) or ecasound.
sudo xxd /var/lib/squeezeboxserver/airplay-fifo.raw
Shairplay to ALSA loopback approach
In my experience, this approach leads to a much lower latency/delay from source to speaker. It requires the ALSA loopback device, I discuss setting up the ALSA loopback device here.
Loopback describes ways of routing electronic signals / digital data streams from their originating facility back to the source without intentional processing or modification. This is primarily a means of testing the transmission. It is used here to loop the sound from Shairplay into the Logitech Media Server via and encoder.
The flow of music under this approach is:
iTunes / iOS
> via Airplay
> Shairport on Ubuntu
> ALSA loopback device input
> ALSA loopback device output
> ecasound on Ubuntu (to transcode the raw Airplay stream to compressed FLAC, MP3 or raw PCM)
> PCM stream (the lame MP3 stream using this approach is noisy and PCM performs well - note you can easily swap between them)
> WaveInput plugin on the Logitech Media Server (running on Ubuntu)
> via wi-fi or ethernet
> Squeezebox
> speakers
Create the alsa loopback device
See here.
There are now two options of encoder you can use:
arecord: which I found easier to set up but has issues related to the amount of data it can encode leading to the stream cutting out after 2-3 hours; or
ecasound: which should perform better as it introduces a buffer.
Running with an alsa loopback device using arecord
The loopback input used by shairport is hw:Loopback,0 or for me hw:2,0 The loopback output fed to arecord is hw:Loopback,1 or for me hw:2,1
The LMS Favourite on the Squeezebox should be as wavin:hw:Loopback,1
Shairport runs as: sudo perl /usr/bin/shairport/shairport.pl -v -a "Squeezebox Airplay" --ao_driver alsa --ao_devicename=hw:Loopback,0
Custom-convert.conf (default by BPA with an update for pcm streaming) should be edited to:
## wavin
#
wavin pcm * *
# R
[arecord] -d0 -c2 -f S16_LE -r 44100 -twav -D $FILE$
wavin mp3 * *
# RB:{BITRATE=-B %B}
[arecord] -d0 -c2 -f S16_LE -r 44100 -twav -D $FILE$ | [lame] --silent -r -x -q $QUALITY$ -b $BITRATE$ - -
wavin flc * *
# R
[arecord] -d0 -c2 -f S16_LE -r 44100 -twav -D $FILE$ | [flac] -cs --totally-silent --endian=little --channels=2 --sign=signed --bps=16 --sample-rate=44100 --compression-level-0 -
Remember to restart the LMS.
Running with an alsa loopbackdevice using ecasound
The loopback input used by shairport is hw:Loopback,0 or for me hw:2,0
The loopback output fed to ecasound for is the device number hw:2,1 using the loopback device name didn't seem to work.
The LMS Favourite on the Squeezebox should be wavin:hw,2,1 note carefully the difference in syntax with a comma not colon after hw.
Shairport runs as: sudo perl /usr/bin/shairport/shairport.pl -v -a "Squeezebox Airplay" --ao_driver alsa --ao_devicename=hw:Loopback,0
Custom-convert.conf (default by BPA with an update for pcm streaming) should be edited to:
#
#wavin
#
wavin pcm * *
# R
[ecasound] -q -z:db -b:4096 -f:16,2,44100 -i:alsahw,2,1 -o stdout
wavin mp3 * *
# RB:{BITRATE=-B %B}
[ecasound] -q -z:db -b:4096 -f:16,2,44100 -eadb:-60 -i:alsahw,2,1 -o stdout | [lame] --silent -r -x -q $QUALITY$ -b $BITRATE$ - -
wavin flc * *
# R
[ecasound] -q -z:db -b:4096 -f:16,2,44100 -eadb:-60 -i:alsahw,2,1 -o stdout | [flac] -cs --totally-silent --endian=little --channels=2 --sign=signed --bps=16 --sample-rate=44100 --compression-level-0 -
Remember to restart the LMS.
1. Attenuation (i.e. eadb) to reduce the stream volume in the custom-convert.conf
does not appear to work on the pcm stream.
2. ecasound can be debugged to error log by adding -D -dd "$@" 2>/tmp/ecasound.log to the ecasound commands in the custom-convert.conf. The error log can then be read with sudo tail -f -n 20 /tmp/ecasound.log
3. I have some hiss on the ecasound and arecord streams when using the loopback approach and lame. This is despite all other pulse and alsa input interfaces being muted. When the music stream is stopped on shairplay the hiss disappears and attenuation makes no difference. When using the raw pipe approach with lame there is no hiss at all the downside is the huge delay I am experiencing of c. 30 seconds when using the pipe. Now that I have all the options working I'll see if I can improve the latency on the pipe.
4. The lame compression used in conjunction with the loopback appraoch appears to be introducing the hiss since the pcm stream is clean with no hiss at all that I can discern. The pcm stream also only has a 6 second delay.
Summary
My Atom D330 server with Ubuntu 10.04 can send Airplay to the Squeezebox Touch as follows:
- via alsa loopback with ecasound to lame on the fly but this seems to introduce noise and a 8 second delay
- via alsa loopback with ecasound to pcm on the fly without noise and a 6 second delay
- via raw pipe with ecasound to lame on the fly without noise and a 30 second delay
It cannot:
- under my Ubuntu 10.04 setup to convert to FLAC on the fly via alsa loopback or the pipe (CPU not powerful enough?!)
- pass the raw pipe to the squeezebox via PCM, this leads to huge delays and lots of stuttering. I thought this was bandwidth related but it cannot be if the pcm stream plays using the alsaloop back mechanism.
This is tested with iTunes and iOS on an iPhone 3GS. So for the time being I will be sticking with alsa loopback, ecasound and pcm until I can reduce the delay on the pipe.
Outstanding
- Set up Shairplay as a service with stop and start commands to run at boot.
- Reduce the delay on the raw pipe.
Sources:
https://github.com/albertz/shairport
http://code.google.com/p/bpaplugins/
http://blog.stuart.shelton.me/archives/762
http://forums.slimdevices.com/showthread.php?49584-Announce-WaveInput-for-Linux
Credit to BPA and Ralphy on the Logitech forums for their assistance.
I came across your instructions above and have almost an identical set-up (Ubuntu 12.04). Everything seems to have worked, but I'm not hearing any sound from my player: my iPhone recognized and sent audio to the LMS and I saw normal messages at the CLI.
ReplyDeleteI think my problem is to do with the LMS plugin. With the favourite I created, when I click on the associated "Play" button, nothing appears to happen.
Can I ask what happens when you click on the "Play" button of the web interface?
I've posted the output of the LMS log here: http://forums.slimdevices.com/showthread.php?49584-Announce-WaveInput-for-Linux&p=717487&viewfull=1#post717487
Any insight would be appreciated.
cheers,
S.
Found my problem... seems WaveInput didn't install properly when I first enabled it. Now, everything is working as it should--thanks for the how-to!
ReplyDeleteJust wondering if you got any further on creating a service wrapper? If not, I'm going to start to take a stab at it.
cheers,
S.
Glad to hear that. Sadly I haven't had the opportunity to work on a service script yet. Stuarts blog has a sevice script but it doesn't work as is on Ubuntu it may help. If you crack it I'd gladly test and host a script. Unfortunately my shairplay seems to conflict with my airport express on the same network which I need to sort first before I refine the shairplay service.
DeleteTurns out to be VERY simple! I only needed to modify the included init script:
Deletejuggler@server:~$ sudo cp /usr/bin/shairport/shairport.init.sample /etc/init.d/shairport
juggler@server:~$ sudo vi /etc/init.d/shairport
change the following two lines
DAEMON="/usr/bin/shairport.pl"
DAEMON_ARGS="-a Squeezebox -w $PIDFILE --pipe=/var/lib/squeezeboxserver/airplay-fifo.raw"
juggler@server:~$ sudo update-rc.d shairport defaults
Do you have an actual Airport Express as well?
DeleteI do (older version, wall-wart style). Also have a Raspberry Pi running OpenElec (XBMC distribution)--this also includes Airplay support. Both are working even with Shairport running.
DeleteMy router is an ASUS running Tomato; currently I have not enabled any IPv6 settings on the router.
Thanks similar set up with an RPi, latest AirportExpress and a DD-WRT router without IPv6 here still not got to the bottom of this.
DeleteFrustrating. I'm running Ubuntu Server 12.04. There were some updates yesterday including Linux headers etc. After updating, I'm no longer able to connect my iDevices--when I attempt to, I get the following error from Shairport before it crashes:
ReplyDeleteOdd number of elements in hash assignment at /usr/bin/shairport.pl line 636.
Use of uninitialized value in subroutine entry at /usr/bin/shairport.pl line 637.
no AESIV at /usr/bin/shairport.pl line 637.
Any insights?
I've not experienced that issue but I am running on 10.04. Are you connecting from iOS6 or OSX 10.8 Lion...
DeleteI see you've also logged a bug over at GitHub.
I am still trying to resolve my AirportExpress conflict do you specify a MAC address in your shaiport command line?
Well that's embarassing... your comment twigged me to the fact that it is actually iOS6 that has broken Shairport and not any Ubuntu package upgrades (confirmed on another iDevice that hasn't yet upgraded to iOS6).
ReplyDeleteI'm using the exact command line you provided above... no MAC specified.
Hi, I have done this whole installation on a Pi, with Squeezeplug, everything is working, but I hardly get and audio its mostly hiss, any suggestions.
ReplyDeleteOff the top of my head I cannot remember, sometimes it was permissions related.
DeleteIf you have hiss the easiest option is to use the pipe method.
Although from testing on my own RPi I don't think the RPi has sufficient power to transcode the streams for AirPlay.
Thanks for a great tutorial.
ReplyDeleteI have some issues installing this on a pi. I cant get the following command to work:
sudo perl -MCPAN -e 'install IO::Socket::INET6'
Did you do anything special? Im running squeezeplug on my rPi.
I think on the current RPi raspbian builds this is no longer required.
DeleteBut it seems like i dont need it, now it is working on my setup.
ReplyDeleteI used the first method and have the buffering issues
I will try the second method to see if it solves the issues.
On my RPi when trying this under either method I experienced unusable lag, I don't think the RPi has enough grunt to do this. That set up was using the RPi as a client only and not using it as a server.
DeleteHi, I’ve finaly made something equivalent for Windows Squeezebox server. You can find it here :
ReplyDeletehttp://forums.slimdevices.com/showthread.php?100048
Many thanks, great tutorial, works like a charm! (Ubuntu 12.04, iPhone 4S, iOS 7)
ReplyDeleteI used the raw pipe method. There's indeed a delay, but on my HTPC (Celeron 1.2GHz) it's only oa couple of seconds, I can live with that.
Awesome stuff you've blogged about here. I consider myself the lucky owner of SB Touch but am now falling in love with the simplicity and elegance of Plex. So my dream is to combine the best of both worlds and make my SB Touch a valid player for Plex. I'm hoping to be able to use your instructions for this (since Plex can use AirPlay targets), but my SB server is running 14.04 and is virtualized. Will this make a lot of difference?
ReplyDeleteYour best bet is shairport2 SBT plugin. It will work with a virtual server but you need to ensure that the networking on the VM is bridged to the host as airplay requires dynamic assigned ports.
DeleteFor automatically starting the airplay input, I've done this:
ReplyDeleteIn shairport config:
sessioncontrol =
{
run_this_before_play_begins = "/opt/scripts/play-airplay.sh";
};
And the script contains:
#!/bin/bash
echo favorites playlist play item_id:c7bdbce1.6 | nc -q 1 192.168.2.21 9090 >/dev/null
You'll need to modify the item_id to whatever it is on your setup of course.
google 1262
ReplyDeletegoogle 1263
google 1264
google 1265
google 1059
ReplyDeletegoogle 1060
google 1061
google 1062
google 1063
google 1064
google 1065
I stumble on this site when I was making research on my project topic. I found some useful topics in well detail form. Thanks for this excellent post. Feel free to visit my website; 먹튀검증
ReplyDeleteSweet blog! I found it while browsing on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Thank you Also visit my site: Feel free to visit my website; 바카라사이트
ReplyDeleteI am happy to find your distinguished way of writing the post. Now you make it easy for me to understand and implement the concept. Thank you for the post. Feel free to visit my website; 토토사이트
ReplyDeleteincluding supporting all operating systems Whether the operating system of the phone, iPad pgslot เว็บตรง
ReplyDeleteTHE BEST ONLINE FOR YOU There are over 300 slot games to choose from. from all slot game camps in pgslot
ReplyDeleteYou can play the game with fun. Enjoy beautiful slot game images. and also add excitement pgslot เว็บตรง
ReplyDeletematter what type of gambling game, our camp is ready to pgslot เว็บตรง
ReplyDeleteSo let's get to know each other better today. First of all, we have to say that slots games in the past pgslot เว็บตรง
ReplyDeleteYou will get fun, worthwhile, playing free games. I guarantee that everyone will like it for sure 100%. pgslot
ReplyDeletecome out with a variety of systems To allow players to play online slots games more easily. It also has to add a helper. pgslot
ReplyDeletethat we have selected but focusing on quality games Let everyone play together comfortably. ดูบอลสด
ReplyDeleteOne, and this number is a number of power and power, full of luck and prestige for the number. บอลนะจ๊ะ
ReplyDeleteEasier than before. Try playing virtual slots at PG SLOT in one place. We are ready to give credit. ข่าววันนี้
ReplyDeleteOur automatic system or Slot Auto is 100% safe, everyone can be confident that you will receive fast service within 1 AMBKING
ReplyDeleteOnline slot games, slots, withdraw money from here, 24-hour automatic service, 100% safe and secure. pgslot
ReplyDelete