本文转载自 王晔的流水账。
之前有一篇文章介绍了如何使用蓝牙实现手机连接无线音箱外放,在网上搜索相关资料的过程中,我发现了树莓派另外一个强大的功能,那就是可以实现苹果(Apple)的AirPlay播放技术,简单的介绍一下,AirPlay类似于蓝牙音响播放,但是其是建立在WiFi局域网基础上的,在接入有AirPlay播放技术的局域网上,苹果的设备就会显示支持AirPlay。综合AirPlay的优势,我开始在Raspberry Pi(树莓派)上实现相关功能。
同样的,关于树莓派一些好玩的功能国外资料较为丰富,经过查阅后《Raspberry Pi Airplay Tutorial》(原文超级详细)这一篇文章对我帮助较大,具体步骤如下。
1. 升级Raspberry Pi系统的软件
1 2  | sudo apt-get updatesudo apt-get upgrade | 
2. 将音频输出变更为默认的音频输出口
通常情况下树莓派的音频输出使用的是HDMI接口,我们需要下面的命令将其变更为普通音频输出口:
1  | sudo amixer cset numid=3 1 | 
这一步我遇到一个错误:
1 2 3  | ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Access deniedamixer: Control default open error: Connection refused | 
提示没有权限,如果不使用sudo则没有这类问题,比较郁闷。如果你也遇到同样的问题,先跳过,我们继续下面的步骤。
3. 安装系统所必需的软件包
1 2 3  | sudo apt-get install git libao-dev libssl-devsudo apt-get install libcrypt-openssl-rsa-perl libio-socket-inet6-perlsudo apt-get install libwww-perl avahi-utils libmodule-build-perl | 
4. 安装Perl Net-SDP协议软件
1 2 3 4 5 6 7 8  | cd ~git clone https://github.com/njh/perl-net-sdp.git perl-net-sdpcd perl-net-sdpperl Build.PLsudo ./Buildsudo ./Build testsudo ./Build installcd .. | 
5. 使用Shairport将树莓派设置为AirPlay接收器
1 2 3 4  | cd ~git clone https://github.com/hendrikw82/shairport.gitcd shairportmake | 
6. 启动Shairport以支持AirPlay
1  | ./shairport.pl -a WangyePi | 
这里我们指定了一个名字叫做WangyePi,大家可以根据实际进行修改,自此,你可以使用苹果设备来访问AirPlay了,当然每次使用这个命令略显不便,下面介绍如何将其变成系统服务。
7. 将Shairport设置为系统服务
1 2 3 4 5 6 7  | cd shairportsudo make installsudo cp shairport.init.sample /etc/init.d/shairportcd /etc/init.dsudo chmod a+x shairportsudo update-rc.d shairport defaults | 
好了,上面的步骤将移植Shairport到系统路径下,同时创建名称为shairport的服务,你可以使用sudo service控制这个服务。
接下来编辑这个启动文件:
1  | sudo nano /etc/init.d/shairport | 
找到DAEMON_ARGS="-w $PIDFILE"这行,并且修改成DAEMON_ARGS="-w $PIDFILE -a WangyePi",同样的这里WangyePi为你的AirPlay名字。
启动AirPlay看看效果吧:
1  | sudo service shairport start | 
8. 一些问题
如果上面步骤完成后一切正常的话,那么恭喜你,这一步可以略过了。我亲自试验下来没有那么顺利,假如AirPlay不能播放的话,建议使用tail /var/log/syslog命令查看系统日志以便于确定问题原因,比如我就遇到下面的错误:
May 11 04:57:05 raspberrypi pulseaudio[2563]: [pulseaudio] protocol-native.c: Denied access to client with invalid authorization data.
具体的处理方式如下,之前我注意到sudo amixer cset numid=3 1命令会导致pulseaudio拒绝访问报错,特诡异,居然管理员权限还有不能访问的资源。
然后我检查了pulseaudio和shairport启动的用户,发现pulseaudio是以pulse账户启动的,而shairport是以root身份启动的,很有可能问题出在这儿,我们只需要让两个都以pulse账户启动就万事大吉了。
命令sudo nano /etc/init.d/shairport修改shairport启动文件,将PIDFILE=/var/run/$NAME.pid改为PIDFILE=/var/run/shairport/$NAME.pid,然后找到两处start-stop-daemon,分别加上-c pulse参数,我的最终修改如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65  | #!/bin/bash## This starts and stops shairport#### BEGIN INIT INFO# Provides:          shairport# Required-Start:    $network# Required-Stop:# Short-Description: shairport - Airtunes emulator!# Description:       Airtunes emulator!# Default-Start:     2 3 4 5# Default-Stop:      0 1 6### END INIT INFO# Source function library.. /lib/lsb/init-functionsNAME=shairportDAEMON="/usr/local/bin/shairport.pl"PIDFILE=/var/run/shairport/$NAME.pidDAEMON_ARGS="-w $PIDFILE -a AirPi"[ -x $binary ] || exit 0RETVAL=0start() {    echo -n "Starting shairport: "    start-stop-daemon -c pulse --start --quiet --pidfile "$PIDFILE" \                      --exec "$DAEMON" -b --oknodo -- $DAEMON_ARGS    log_end_msg $?}stop() {    echo -n "Shutting down shairport: "    start-stop-daemon -c pulse --stop --quiet --pidfile "$PIDFILE" \                --retry 1 --oknodo    log_end_msg $?}restart() {    stop    sleep 1    start}case "$1" in    start)        start    ;;    stop)        stop    ;;    status)        status shairport    ;;    restart)        restart    ;;    *)        echo "Usage: $0 {start|stop|status|restart}"    ;;esacexit 0 | 
然后创建PID所在文件夹并设置权限:
1 2  | sudo mkdir /var/run/shairportsudo chown pulse /var/run/shairport | 
最后重启shairport服务,看看是不是正常了。
1  | sudo service shairport restart | 
参考文档
2014年5月12日更新
在上面第8点有些问题的叙述上需要更正一下,今天发现建立在/var/run路径下的shairport目录消失,导致shairport启动失败,于是我将启动文件/etc/init.d/shairport修改如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70  | #!/bin/bash## This starts and stops shairport#### BEGIN INIT INFO# Provides:          shairport# Required-Start:    $network# Required-Stop:# Short-Description: shairport - Airtunes emulator!# Description:       Airtunes emulator!# Default-Start:     2 3 4 5# Default-Stop:      0 1 6### END INIT INFO# Source function library.. /lib/lsb/init-functionsNAME=shairportDAEMON="/usr/local/bin/shairport.pl"PIDDIR=/var/run/shairportPIDFILE=$PIDDIR/$NAME.pidDAEMON_ARGS="-w $PIDFILE -a AirPi"[ -x $binary ] || exit 0RETVAL=0start() {    echo -n "Starting shairport: "    if [ ! -d $PIDDIR ]; then        mkdir -p $PIDDIR        chown pulse:pulse $PIDDIR    fi    start-stop-daemon -c pulse --start --quiet --pidfile "$PIDFILE" \                      --exec "$DAEMON" -b --oknodo -- $DAEMON_ARGS    log_end_msg $?}stop() {    echo -n "Shutting down shairport: "    start-stop-daemon -c pulse --stop --quiet --pidfile "$PIDFILE" \                --retry 1 --oknodo    log_end_msg $?}restart() {    stop    sleep 1    start}case "$1" in    start)        start    ;;    stop)        stop    ;;    status)        status shairport    ;;    restart)        restart    ;;    *)        echo "Usage: $0 {start|stop|status|restart}"    ;;esacexit 0 | 

第5步的make有错误
‘
Perhaps you should add the directory containing `ao.pc’
to the PKG_CONFIG_PATH environment variable
No package ‘ao’ found
cc -O2 -Wall -DHAIRTUNES_STANDALONE hairtunes.c alac.o -o hairtunes -lm -lpthread
hairtunes.c:37:25: fatal error: openssl/aes.h: No such file or directory
#include
^
compilation terminated.
Makefile:7: recipe for target ‘hairtunes’ failed
make: *** [hairtunes] Error 1
‘
如何 关闭 Airplay 呢?
现在都不用这个,改用shairport-sync