树莓派Raspberry Pi用AirPlay播放实现WiFi连无线音响外放
提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!
之前 有一篇文章 介绍了如何使用蓝牙实现手机连接无线音箱外放,在网上搜索相关资料的过程中,我发现了树莓派另外一个强大的功能,那就是可以实现苹果(Apple)的AirPlay播放技术,简单的介绍一下,AirPlay类似于蓝牙音响播放,但是其是建立在WiFi局域网基础上的,在接入有AirPlay播放技术的局域网上,苹果的设备就会显示支持AirPlay。综合AirPlay的优势,我开始在Raspberry Pi(树莓派)上实现相关功能。
同样的,关于树莓派一些好玩的功能国外资料较为丰富,经过查阅后 《Raspberry Pi Airplay Tutorial》 (原文超级详细)这一篇文章对我帮助较大,具体步骤如下。
1. 升级Raspberry Pi系统的软件
sudo apt-get update
sudo apt-get upgrade
2. 将音频输出变更为默认的音频输出口
通常情况下树莓派的音频输出使用的是HDMI接口,我们需要下面的命令将其变更为普通音频输出口:
sudo amixer cset numid=3 1
这一步我遇到一个错误:
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Access denied amixer: Control default open error: Connection refused
提示没有权限,如果不使用sudo则没有这类问题,比较郁闷。如果你也遇到同样的问题,先跳过,我们继续下面的步骤。
3. 安装系统所必需的软件包
sudo apt-get install git libao-dev libssl-dev
sudo apt-get install libcrypt-openssl-rsa-perl libio-socket-inet6-perl
sudo apt-get install libwww-perl avahi-utils libmodule-build-perl
4. 安装Perl Net-SDP协议软件
cd ~
git clone https://github.com/njh/perl-net-sdp.git perl-net-sdp
cd perl-net-sdp
perl Build.PL
sudo ./Build
sudo ./Build test
sudo ./Build install
cd ..
5. 使用Shairport将树莓派设置为AirPlay接收器
cd ~
git clone https://github.com/hendrikw82/shairport.git
cd shairport
make
6. 启动Shairport以支持AirPlay
./shairport.pl -a WangyePi
这里我们指定了一个名字叫做WangyePi,大家可以根据实际进行修改,自此,你可以使用苹果设备来访问AirPlay了,当然每次使用这个命令略显不便,下面介绍如何将其变成系统服务。
7. 将Shairport设置为系统服务
cd shairport
sudo make install
sudo cp shairport.init.sample /etc/init.d/shairport
cd /etc/init.d
sudo chmod a+x shairport
sudo update-rc.d shairport defaults
好了,上面的步骤将移植Shairport到系统路径下,同时创建名称为shairport的服务,你可以使用
sudo service
控制这个服务。
接下来编辑这个启动文件:
sudo nano /etc/init.d/shairport
找到
DAEMON_ARGS="-w $PIDFILE"
这行,并且修改成
DAEMON_ARGS="-w $PIDFILE -a WangyePi"
,同样的这里WangyePi为你的AirPlay名字。
启动AirPlay看看效果吧:
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
参数,我的最终修改如下:
#!/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-functions
NAME=shairport
DAEMON="/usr/local/bin/shairport.pl"
PIDFILE=/var/run/shairport/$NAME.pid
DAEMON_ARGS="-w $PIDFILE -a AirPi"
[ -x $binary ] || exit 0
RETVAL=0
start() {
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}"
;;
esac
exit 0
然后创建PID所在文件夹并设置权限:
sudo mkdir /var/run/shairport
sudo chown pulse /var/run/shairport
最后重启shairport服务,看看是不是正常了。
sudo service shairport restart
参考文档
2014年5月12日更新
在上面第8点有些问题的叙述上需要更正一下,今天发现建立在
/var/run
路径下的
shairport
目录消失,导致shairport启动失败,于是我将启动文件
/etc/init.d/shairport
修改如下:
#!/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-functions
NAME=shairport
DAEMON="/usr/local/bin/shairport.pl"
PIDDIR=/var/run/shairport
PIDFILE=$PIDDIR/$NAME.pid
DAEMON_ARGS="-w $PIDFILE -a AirPi"
[ -x $binary ] || exit 0
RETVAL=0
start() {
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}"
;;
esac
exit 0
我和一个朋友在讨论4G模块+R-Pi+WiFi构建一个路由器。这些配置问题不大,但是缺少一个Web UI,您有这方面的资讯么?
你可以试试一些mini的Web服务器程序,比如mini-httpd,可以使用sudo apt-get install mini-httpd安装,当然这类简单的CGI服务程序还有很多,按你们的喜好选择。安装完成后可以使用root权限运行该Web服务,再配合你们编写的CGI脚本(可以是C/C++、Python或者Perl编写的)就可以实现Web控制了。
太棒了!之前我找了好多用树莓派做airplay的文章,没一个成功的,都不知道是哪里出问题。按照您的这个教程很快就成功了!太谢谢了
关于shairport使用声音服务Access Denied的问题,你将运行shairport进程的用户加入pulse-access组就可以了。
感谢你的提供:-)
请问,如果想要树莓派输出到蓝牙音箱上,而不是HDMI音频或3.5接口音频,怎样操作呢?已经在系统中配对蓝牙音箱并连接成功,使用树莓派GUI界面中的浏览器、VLC播放器都是蓝牙音箱出声,但airplay,还是3.5接口的音频设备。谢谢
你好,问题已解决,因为偷懒,在docker里运行了,直接在外面安装就行了。谢谢
不客气哦,很高兴你的问题得到了解决。